added project support, codetools

git-svn-id: trunk@210 -
This commit is contained in:
lazarus 2001-03-03 11:06:18 +00:00
parent 461f8e25db
commit 934f6aff7c
11 changed files with 3762 additions and 1238 deletions

2
.gitattributes vendored
View File

@ -61,6 +61,7 @@ examples/testtools.inc svneol=native#text/pascal
examples/toolbar.pp svneol=native#text/pascal
examples/trackbar.pp svneol=native#text/pascal
ide/codetemplatedialog.pp svneol=native#text/pascal
ide/codetools.pp svneol=native#text/pascal
ide/compiler.pp svneol=native#text/pascal
ide/compileroptions.pp svneol=native#text/pascal
ide/compreg.pp svneol=native#text/pascal
@ -84,6 +85,7 @@ ide/lazarus.pp svneol=native#text/pascal
ide/lazconf.pp svneol=native#text/pascal
ide/lazres.pp svneol=native#text/pascal
ide/main.pp svneol=native#text/pascal
ide/newprojectdlg.pp svneol=native#text/pascal
ide/project.pp svneol=native#text/pascal
ide/splash.pp svneol=native#text/pascal
ide/testform.pp svneol=native#text/pascal

View File

@ -1097,6 +1097,7 @@ destructor TCustomSynEdit.Destroy;
var
i: integer;
begin
writeln('[TCustomSynEdit.Destroy]');
Highlighter := nil;
// free listeners while other fields are still valid
if Assigned(fHookedCommandHandlers) then begin
@ -1487,7 +1488,8 @@ var
C: char;
Cmd: TSynEditorCommand;
begin
//writeln('[TCustomSynEdit.KeyDown]');
//writeln('[TCustomSynEdit.KeyDown] ',Key
// ,' Shift=',ssShift in Shift,' Ctrl=',ssCtrl in Shift,' Alt=',ssAlt in Shift);
inherited;
Data := nil;
C := #0;
@ -1727,9 +1729,7 @@ end;
procedure TCustomSynEdit.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
writeln('TCustomSynEdit.MouseUp 1');
inherited MouseUp(Button, Shift, X, Y);
writeln('TCustomSynEdit.MouseUp 2');
{$IFDEF SYN_LAZARUS}
if (X>=ClientWidth-ScrollBarWidth) or (Y>=ClientHeight-ScrollBarWidth) then
begin
@ -4572,13 +4572,15 @@ const
{$ENDIF}
begin
i := KeyStrokes.FindKeycode2(fLastKey, fLastShiftState, Code, Shift);
if i >= 0 then
if i >= 0 then begin
//writeln('FindKeyCode2 success');
Result := KeyStrokes[i].Command
else begin
end else begin
i := Keystrokes.FindKeycode(Code, Shift);
if i >= 0 then
if i >= 0 then begin
//writeln('FindKeyCode success');
Result := Keystrokes[i].Command
else
end else
Result := ecNone;
end;
if (Result = ecNone) and (Code >= VK_ACCEPT) and (Code <= VK_SCROLL) then

View File

@ -708,6 +708,10 @@ begin
for x := 0 to Count-1 do
if (Items[x].Key = Code) and (Items[x].Shift = SS) and (Items[x].Key2 = 0)
then begin
writeln('TSynEditKeyStrokes.FindKeycode ',Items[x].Key,'=',Code
,' Shift ',ssShift in Items[x].Shift,'=',ssShift in SS
,' Ctrl ',ssCtrl in Items[x].Shift,'=',ssCtrl in SS
);
Result := x;
break;
end;
@ -902,3 +906,4 @@ initialization
EditorCommandToIdent);
{$ENDIF}
end.

View File

@ -115,8 +115,15 @@ begin
if CompTableSensitive <> Sensitive then
begin
CompTableSensitive := Sensitive;
{$IFDEF FPC}
if Sensitive then
for I := #0 to #255 do CompTable[I] := ord(I)
else
for I := #0 to #255 do CompTable[I] := ord(lowercase(I)[1]);
{$ELSE}
for I := #0 to #255 do CompTable[I] := ord(I);
if not Sensitive then CharLowerBuff(PChar(@CompTable[#0]), 256);
{$ENDIF}
end;
end;
@ -245,6 +252,7 @@ end;
procedure TSynEditSearch.SetSensitive(const Value: Boolean);
begin
if fSensitive <> Value then begin
writeln('A');
fSensitive := Value;
MakeCompTable(Value);
fShiftInitialized := FALSE;

857
ide/codetools.pp Normal file
View File

@ -0,0 +1,857 @@
{
Author: Mattias Gaertner
Abstract:
Functions for automatic code editing.
This unit should eventually contain the frontend of the parser.
ToDo:
-compiler directives
}
unit CodeTools;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils;
// program name
function RenameProgramInSource(var Source:string;
NewProgramName:string):boolean;
function FindProgramNameInSource(Source:string;
var ProgramNameStart,ProgramNameEnd:integer):string;
// unit name
function RenameUnitInSource(var Source:string; NewUnitName:string):boolean;
function FindUnitNameInSource(Source:string;
var UnitNameStart,UnitNameEnd:integer):string;
// uses sections
function UnitIsUsedInSource(Source,UnitName:string):boolean;
function RenameUnitInProgramUsesSection(var Source:string;
OldUnitName, NewUnitName, NewInFile:string): boolean;
function AddToProgramUsesSection(var Source:string;
AUnitName,InFileName:string):boolean;
function RemoveFromProgramUsesSection(var Source:string;
AUnitName:string):boolean;
function RenameUnitInInterfaceUsesSection(var Source:string;
OldUnitName, NewUnitName, NewInFile:string): boolean;
function AddToInterfaceUsesSection(var Source:string;
AUnitName,InFileName:string):boolean;
function RemoveFromInterfaceUsesSection(var Source:string;
AUnitName:string):boolean;
function IsUnitUsedInUsesSection(Source,UnitName:string;
UsesStart:integer):boolean;
function RenameUnitInUsesSection(var Source: string; UsesStart: integer;
OldUnitName, NewUnitName, NewInFile:string): boolean;
function AddUnitToUsesSection(var Source:string; UnitName,InFilename:string;
UsesStart:integer):boolean;
function RemoveUnitFromUsesSection(var Source:string; UnitName:string;
UsesStart:integer):boolean;
// compiler directives
function FindIncludeDirective(Source,Section:string; Index:integer;
var IncludeStart,IncludeEnd:integer):boolean;
function SplitCompilerDirective(Directive:string;
var DirectiveName,Parameters:string):boolean;
// createform
function AddCreateFormToProgram(var Source:string;
AClassName,AName:string):boolean;
function RemoveCreateFormFromProgram(var Source:string;
AClassName,AName:string):boolean;
function CreateFormExistsInProgram(Source:string;
AClassName,AName:string):boolean;
function ListAllCreateFormsInProgram(Source:string):TStrings;
// resource code
function FindResourceInCode(Source:string; AddCode:string;
var Position,EndPosition:integer):boolean;
function AddResourceCode(var Source:string; AddCode:string):boolean;
// code search
function SearchCodeInSource(Source,Find:string; StartPos:integer;
var EndFoundPosition:integer; CaseSensitive:boolean):integer;
procedure GetLineStartEndAtPosition(Source:string; Position:integer;
var LineStart,LineEnd:integer);
function ReadNextPascalAtom(Source:string;
var Position,AtomStart:integer):string;
function ReadRawNextPascalAtom(Source:string;
var Position,AtomStart:integer):string;
const MaxLineLength:integer=80;
implementation
const
IdentifierStartChar = ['a'..'z','A'..'Z','_'];
IdentifierChar = ['a'..'z','A'..'Z','_','0'..'9'];
// ToDo: find the constant in the fpc units.
EndOfLine:shortstring={$IFDEF win32}#13{$ENDIF}#10;
function FindIncludeDirective(Source,Section:string; Index:integer;
var IncludeStart,IncludeEnd:integer):boolean;
var Atom,DirectiveName:string;
Position,EndPos,AtomStart:integer;
Filename:string;
begin
Result:=false;
// find section
Position:=SearchCodeInSource(Source,Section,1,EndPos,false);
if Position<1 then exit;
// search for include directives
repeat
Atom:=ReadNextPascalAtom(Source,Position,AtomStart);
if (copy(Atom,1,2)='{$') or (copy(Atom,1,3)='(*$') then begin
SplitCompilerDirective(Atom,DirectiveName,Filename);
DirectiveName:=lowercase(DirectiveName);
if (DirectiveName='i') or (DirectiveName='include') then begin
// include directive
dec(Index);
if Index=0 then begin
IncludeStart:=AtomStart;
IncludeEnd:=Position;
Result:=true;
exit;
end;
end;
end;
until Atom='';
end;
function SplitCompilerDirective(Directive:string;
var DirectiveName,Parameters:string):boolean;
var EndPos,DirStart,DirEnd:integer;
begin
if (copy(Directive,1,2)='{$') or (copy(Directive,1,3)='(*$') then begin
if copy(Directive,1,2)='{$' then begin
DirStart:=3;
DirEnd:=length(Directive);
end else begin
DirStart:=4;
DirEnd:=length(Directive)-1;
end;
EndPos:=DirStart;
while (EndPos<DirEnd) and (Directive[EndPos] in IdentifierChar) do
inc(EndPos);
DirectiveName:=lowercase(copy(Directive,DirStart,EndPos-DirStart));
Parameters:=copy(Directive,EndPos+1,DirEnd-EndPos+1);
Result:=true;
end else
Result:=false;
end;
function RenameUnitInSource(var Source:string; NewUnitName:string):boolean;
var UnitNameStart,UnitNameEnd:integer;
begin
UnitNameStart:=0;
UnitNameEnd:=0;
Result:=(FindUnitNameInSource(Source,UnitNameStart,UnitNameEnd)<>'');
if Result then
Source:=copy(Source,1,UnitNameStart-1)
+NewUnitName
+copy(Source,UnitNameEnd,length(Source)-UnitNameEnd+1);
end;
function FindUnitNameInSource(Source:string;
var UnitNameStart,UnitNameEnd:integer):string;
begin
UnitNameStart:=SearchCodeInSource(Source,'unit',1,UnitNameEnd,false);
if UnitNameStart>0 then
Result:=ReadNextPascalAtom(Source,UnitNameEnd,UnitNameStart)
else
Result:='';
end;
function RenameProgramInSource(var Source:string;
NewProgramName:string):boolean;
var ProgramNameStart,ProgramNameEnd:integer;
begin
Result:=(FindProgramNameInSource(Source,ProgramNameStart,ProgramNameEnd)<>'');
if Result then
Source:=copy(Source,1,ProgramNameStart-1)
+NewProgramName
+copy(Source,ProgramNameEnd,length(Source)-ProgramNameEnd+1);
end;
function FindProgramNameInSource(Source:string;
var ProgramNameStart,ProgramNameEnd:integer):string;
begin
ProgramNameStart:=SearchCodeInSource(Source,'program',1,ProgramNameEnd,false);
if ProgramNameStart>0 then
Result:=ReadNextPascalAtom(Source,ProgramNameEnd,ProgramNameStart)
else
Result:='';
end;
function UnitIsUsedInSource(Source,UnitName:string):boolean;
// search in all uses sections
var UsesStart,UsesEnd:integer;
begin
Result:=false;
repeat
UsesStart:=SearchCodeInSource(Source,'uses',1,UsesEnd,false);
if UsesStart>0 then begin
if IsUnitUsedInUsesSection(Source,UnitName,UsesStart) then begin
Result:=true;
exit;
end;
end;
until UsesStart<1;
end;
function RenameUnitInProgramUsesSection(var Source:string;
OldUnitName, NewUnitName, NewInFile:string): boolean;
var
ProgramTermStart,ProgramTermEnd,
UsesStart,UsesEnd:integer;
begin
Result:=false;
// search Program section
ProgramTermStart:=SearchCodeInSource(Source,'program',1,ProgramTermEnd,false);
if ProgramTermStart<1 then exit;
// search programname
ReadNextPascalAtom(Source,ProgramTermEnd,ProgramTermStart);
// search semicolon after programname
if not (ReadNextPascalAtom(Source,ProgramTermEnd,ProgramTermStart)=';') then exit;
UsesEnd:=ProgramTermEnd;
ReadNextPascalAtom(Source,UsesEnd,UsesStart);
if UsesEnd>length(Source) then exit;
if not (lowercase(copy(Source,UsesStart,UsesEnd-UsesStart))='uses') then begin
// no uses section in interface -> add one
Source:=copy(Source,1,ProgramTermEnd-1)
+EndOfLine+EndOfLine+'uses'+EndOfLine+' ;'
+copy(Source,ProgramTermEnd,length(Source)-ProgramTermEnd+1);
UsesEnd:=ProgramTermEnd;
ReadNextPascalAtom(Source,UsesEnd,UsesStart);
end;
if not (lowercase(copy(Source,UsesStart,UsesEnd-UsesStart))='uses') then exit;
Result:=RenameUnitInUsesSection(Source,UsesStart,OldUnitName
,NewUnitName,NewInFile);
end;
function AddToProgramUsesSection(var Source:string;
AUnitName,InFileName:string):boolean;
var
ProgramTermStart,ProgramTermEnd,
UsesStart,UsesEnd:integer;
begin
Result:=false;
if (AUnitName='') or (AUnitName=';') then exit;
// search program
ProgramTermStart:=SearchCodeInSource(Source,'program',1,ProgramTermEnd,false);
if ProgramTermStart<1 then exit;
// search programname
ReadNextPascalAtom(Source,ProgramTermEnd,ProgramTermStart);
// search semicolon after programname
if not (ReadNextPascalAtom(Source,ProgramTermEnd,ProgramTermStart)=';') then exit;
// search uses section
UsesEnd:=ProgramTermEnd;
ReadNextPascalAtom(Source,UsesEnd,UsesStart);
if UsesEnd>length(Source) then exit;
if not (lowercase(copy(Source,UsesStart,UsesEnd-UsesStart))='uses') then begin
// no uses section after program term -> add one
Source:=copy(Source,1,ProgramTermEnd-1)
+EndOfline+EndOfline+'uses'+EndOfline+' ;'
+copy(Source,ProgramTermEnd,length(Source)-ProgramTermEnd+1);
UsesEnd:=ProgramTermEnd;
ReadNextPascalAtom(Source,UsesEnd,UsesStart);
end;
if not (lowercase(copy(Source,UsesStart,UsesEnd-UsesStart))='uses') then exit;
Result:=AddUnitToUsesSection(Source,AUnitName,InFileName,UsesStart);
end;
function RenameUnitInInterfaceUsesSection(var Source:string;
OldUnitName, NewUnitName, NewInFile:string): boolean;
var
InterfaceStart,InterfaceWordEnd,
UsesStart,UsesEnd:integer;
begin
Result:=false;
// search interface section
InterfaceStart:=SearchCodeInSource(Source,'interface',1,InterfaceWordEnd,false);
if InterfaceStart<1 then exit;
UsesEnd:=InterfaceWordEnd;
ReadNextPascalAtom(Source,UsesEnd,UsesStart);
if UsesEnd>length(Source) then exit;
if not (lowercase(copy(Source,UsesStart,UsesEnd-UsesStart))='uses') then begin
// no uses section in interface -> add one
Source:=copy(Source,1,InterfaceWordEnd-1)
+EndOfLine+EndOfLine+'uses'+EndOfLine+' ;'
+copy(Source,InterfaceWordEnd,length(Source)-InterfaceWordEnd+1);
UsesEnd:=InterfaceWordEnd;
ReadNextPascalAtom(Source,UsesEnd,UsesStart);
end;
if not (lowercase(copy(Source,UsesStart,UsesEnd-UsesStart))='uses') then exit;
Result:=RenameUnitInUsesSection(Source,UsesStart,OldUnitName
,NewUnitName,NewInFile);
end;
function AddToInterfaceUsesSection(var Source:string;
AUnitName,InFileName:string):boolean;
var
InterfaceStart,InterfaceWordEnd,
UsesStart,UsesEnd:integer;
begin
Result:=false;
if AUnitName='' then exit;
// search interface section
InterfaceStart:=SearchCodeInSource(Source,'interface',1,InterfaceWordEnd,false);
if InterfaceStart<1 then exit;
UsesEnd:=InterfaceWordEnd;
ReadNextPascalAtom(Source,UsesEnd,UsesStart);
if UsesEnd>length(Source) then exit;
if not (lowercase(copy(Source,UsesStart,UsesEnd-UsesStart))='uses') then begin
// no uses section in interface -> add one
Source:=copy(Source,1,InterfaceWordEnd-1)
+EndOfLine+EndOfLine+'uses'+EndOfLine+' ;'
+copy(Source,InterfaceWordEnd,length(Source)-InterfaceWordEnd+1);
UsesEnd:=InterfaceWordEnd;
ReadNextPascalAtom(Source,UsesEnd,UsesStart);
end;
if not (lowercase(copy(Source,UsesStart,UsesEnd-UsesStart))='uses') then exit;
Result:=AddUnitToUsesSection(Source,AUnitName,InFileName,UsesStart);
end;
function RemoveFromProgramUsesSection(var Source:string;
AUnitName:string):boolean;
var
ProgramTermStart,ProgramTermEnd,
UsesStart,UsesEnd:integer;
Atom:string;
begin
Result:=false;
if AUnitName='' then exit;
// search program
ProgramTermStart:=SearchCodeInSource(Source,'program',1,ProgramTermEnd,false);
if ProgramtermStart<1 then exit;
// search programname
ReadNextPascalAtom(Source,ProgramTermEnd,ProgramTermStart);
// search semicolon after programname
if not (ReadNextPascalAtom(Source,ProgramTermEnd,ProgramTermStart)=';') then exit;
UsesEnd:=ProgramTermEnd;
Atom:=ReadNextPascalAtom(Source,UsesEnd,UsesStart);
if UsesEnd>length(Source) then exit;
if not (lowercase(Atom)='uses') then exit;
Result:=RemoveUnitFromUsesSection(Source,AUnitName,UsesStart);
end;
function RemoveFromInterfaceUsesSection(var Source:string;
AUnitName:string):boolean;
var
InterfaceStart,InterfaceWordEnd,
UsesStart,UsesEnd:integer;
Atom:string;
begin
Result:=false;
if AUnitName='' then exit;
// search interface section
InterfaceStart:=SearchCodeInSource(Source,'interface',1,InterfaceWordEnd,false);
if InterfaceStart<1 then exit;
UsesEnd:=InterfaceWordEnd;
Atom:=ReadNextPascalAtom(Source,UsesEnd,UsesStart);
if UsesEnd>length(Source) then exit;
if not (lowercase(Atom)='uses') then exit;
Result:=RemoveUnitFromUsesSection(Source,AUnitName,UsesStart);
end;
function IsUnitUsedInUsesSection(Source,UnitName:string;
UsesStart:integer):boolean;
var UsesEnd:integer;
Atom:string;
begin
Result:=false;
if UnitName='' then exit;
if UsesStart<1 then exit;
if not (lowercase(copy(Source,UsesStart,4))='uses') then exit;
UsesEnd:=UsesStart+4;
// parse through all used units and see if it is there
repeat
Atom:=ReadNextPascalAtom(Source,UsesEnd,UsesStart);
if (lowercase(Atom)=lowercase(UnitName)) then begin
// unit found
Result:=true;
exit;
end;
// read til next comma or semicolon
repeat
Atom:=ReadNextPascalAtom(Source,UsesEnd,UsesStart);
until (Atom=',') or (Atom=';') or (Atom='');
until Atom<>',';
// unit not used
Result:=true;
end;
function RenameUnitInUsesSection(var Source: string; UsesStart: integer;
OldUnitName, NewUnitName, NewInFile:string): boolean;
var UsesEnd:integer;
LineStart,LineEnd,OldUsesStart:integer;
s,Atom:string;
begin
Result:=false;
if (OldUnitName='') then begin
Result:=AddUnitToUsesSection(Source,NewUnitName,NewInFile,UsesStart);
exit;
end;
if (NewUnitName='') or (NewUnitName=';')
or (OldUnitName=';') or (UsesStart<1) then exit;
UsesEnd:=UsesStart+4;
if not (lowercase(copy(Source,UsesStart,4))='uses') then exit;
// parse through all used units and see if it is already there
if NewInFile<>'' then
NewInFile:=' in '''+NewInFile+'''';
s:=', ';
repeat
Atom:=ReadNextPascalAtom(Source,UsesEnd,UsesStart);
if (lowercase(Atom)=lowercase(OldUnitName)) then begin
// unit already used
OldUsesStart:=UsesStart;
// find comma or semicolon
repeat
Atom:=ReadNextPascalAtom(Source,UsesEnd,UsesStart);
until (Atom=',') or (Atom=';') or (Atom='');
Source:=copy(Source,1,OldUsesStart-1)
+NewUnitName+NewInFile
+copy(Source,UsesStart,length(Source)-UsesStart+1);
Result:=true;
exit;
end else if (Atom=';') then begin
s:=' ';
break;
end;
// read til next comma or semicolon
while (Atom<>',') and (Atom<>';') and (Atom<>'') do
Atom:=ReadNextPascalAtom(Source,UsesEnd,UsesStart);
until Atom<>',';
// unit not used yet -> add it
Source:=copy(Source,1,UsesStart-1)
+s+NewUnitName+NewInFile
+copy(Source,UsesStart,length(Source)-UsesStart+1);
GetLineStartEndAtPosition(Source,UsesStart,LineStart,LineEnd);
if (LineEnd-LineStart>MaxLineLength) or (NewInFile<>'') then
Source:=copy(Source,1,UsesStart-1)
+EndOfLine+' '
+copy(Source,UsesStart,length(Source)-UsesStart+1);
Result:=true;
end;
function AddUnitToUsesSection(var Source:string; UnitName,InFilename:string;
UsesStart:integer):boolean;
var UsesEnd:integer;
LineStart,LineEnd:integer;
s,Atom:string;
begin
Result:=false;
if (UnitName='') or (UnitName=';') or (UsesStart<1) then exit;
UsesEnd:=UsesStart+4;
if not (lowercase(copy(Source,UsesStart,4))='uses') then exit;
// parse through all used units and see if it is already there
s:=', ';
repeat
Atom:=ReadNextPascalAtom(Source,UsesEnd,UsesStart);
if (lowercase(Atom)=lowercase(UnitName)) then begin
// unit found
Result:=true;
exit;
end else if (Atom=';') then begin
s:=' ';
break;
end;
// read til next comma or semicolon
while (Atom<>',') and (Atom<>';') and (Atom<>'') do
Atom:=ReadNextPascalAtom(Source,UsesEnd,UsesStart);
until Atom<>',';
// unit not used yet -> add it
if InFilename<>'' then
InFileName:=' in '''+InFileName+'''';
Source:=copy(Source,1,UsesStart-1)
+s+UnitName+InFileName
+copy(Source,UsesStart,length(Source)-UsesStart+1);
GetLineStartEndAtPosition(Source,UsesStart,LineStart,LineEnd);
if (LineEnd-LineStart>MaxLineLength) or (InFileName<>'') then
Source:=copy(Source,1,UsesStart-1)
+EndOfLine+' '
+copy(Source,UsesStart,length(Source)-UsesStart+1);
Result:=true;
end;
function RemoveUnitFromUsesSection(var Source:string; UnitName:string;
UsesStart:integer):boolean;
var UsesEnd,OldUsesStart,OldUsesEnd:integer;
Atom:string;
begin
Result:=false;
if (UsesStart<1) or (UnitName='') or (UnitName=',') or (UnitName=';') then
exit;
// search interface section
UsesEnd:=UsesStart+4;
if not (lowercase(copy(Source,UsesStart,4))='uses') then exit;
// parse through all used units and see if it is there
OldUsesEnd:=-1;
repeat
Atom:=ReadNextPascalAtom(Source,UsesEnd,UsesStart);
if (lowercase(Atom)=lowercase(UnitName)) then begin
// unit found
OldUsesStart:=UsesStart;
// find comma or semicolon
repeat
Atom:=ReadNextPascalAtom(Source,UsesEnd,UsesStart);
until (Atom=',') or (Atom=';') or (Atom='');
if OldUsesEnd<1 then
// first used unit
Source:=copy(Source,1,OldUsesStart-1)
+copy(Source,UsesStart,length(Source)-UsesStart+1)
else
// not first used unit (remove comma in front of unitname too)
Source:=copy(Source,1,OldUsesEnd-1)
+copy(Source,UsesStart,length(Source)-UsesStart+1);
Result:=true;
exit;
end else
OldUsesEnd:=UsesEnd;
// read til next comma or semicolon
while (Atom<>',') and (Atom<>';') and (Atom<>'') do
Atom:=ReadNextPascalAtom(Source,UsesEnd,UsesStart);
until Atom<>',';
// unit not used
end;
function AddCreateFormToProgram(var Source:string;
AClassName,AName:string):boolean;
// insert 'Application.CreateForm(<AClassName>,<AName>);'
// in front of 'Application.Run;'
var Position,EndPosition:integer;
begin
Result:=false;
Position:=SearchCodeInSource(Source,'application.run',1,EndPosition,false);
if Position<1 then exit;
Source:=copy(Source,1,Position-1)
+'Application.CreateForm('+AClassName+','+AName+');'+EndOfLine+' ';
+copy(Source,EndPosition,length(Source)-EndPosition+1);
Result:=true;
end;
function RemoveCreateFormFromProgram(var Source:string;
AClassName,AName:string):boolean;
// remove 'Application.CreateForm(<AClassName>,<AName>);'
var Position,EndPosition:integer;
begin
Result:=false;
Position:=SearchCodeInSource(Source,
';application.createform('+AClassName+','+AName+')',1,EndPosition,false);
if Position<1 then exit;
Source:=copy(Source,1,Position-1)
+copy(Source,EndPosition,length(Source)-EndPosition+1);
Result:=true;
end;
function CreateFormExistsInProgram(Source:string;
AClassName,AName:string):boolean;
var Position,EndPosition:integer;
begin
Position:=SearchCodeInSource(Source,
'application.createform('+AClassName+','+AName+')',1,EndPosition,false);
Result:=Position>0;
end;
function ListAllCreateFormsInProgram(Source:string):TStrings;
// list format: <formname>:<formclassname>
var Position,EndPosition:integer;
s:string;
begin
Result:=TStrings.Create;
Position:=1;
repeat
Position:=SearchCodeInSource(Source,
'application.createform(',Position,EndPosition,false);
if Position>0 then begin
s:=ReadNextPascalAtom(Source,EndPosition,Position);
ReadNextPascalAtom(Source,EndPosition,Position);
s:=ReadNextPascalAtom(Source,EndPosition,Position)+':'+s;
Result.Add(s);
end;
until Position<1;
end;
function FindResourceInCode(Source:string; AddCode:string;
var Position,EndPosition:integer):boolean;
var Find,Atom:string;
FindPosition,FindAtomStart,SemicolonPos:integer;
begin
Result:=false;
if AddCode='' then begin
Result:=true;
exit;
end;
// search "LazarusResources.Add('<ResourceName>',"
repeat
Atom:=ReadNextPascalAtom(Source,FindPosition,FindAtomStart);
until (Atom='') or (Atom=',');
if Atom='' then exit;
// search the resource start in code
Find:=copy(AddCode,1,FindPosition);
Position:=SearchCodeInSource(Source,Find,1,EndPosition,false);
if Position<1 then exit;
// search resource end in code
SemicolonPos:=SearchCodeInSource(Source,');',EndPosition,EndPosition,false);
if SemicolonPos<1 then exit;
Result:=true;
end;
function AddResourceCode(var Source:string; AddCode:string):boolean;
var StartPos,EndPos:integer;
begin
if FindResourceInCode(Source,AddCode,StartPos,EndPos) then begin
// resource exists already -> replace it
Source:=copy(Source,1,StartPos-1)
+AddCode
+copy(Source,EndPos,length(Source)-EndPos+1);
end else begin
// add resource
Source:=Source+EndOfLine+AddCode;
end;
Result:=true;
end;
function SearchCodeInSource(Source,Find:string; StartPos:integer;
var EndFoundPosition:integer; CaseSensitive:boolean):integer;
// search pascal atoms of Find in Source
var FindAtomStart,FindPos,Position,AtomStart
,FirstSrcAtomStart,FirstSrcAtomEnd:integer;
FindAtom,SrcAtom:string;
begin
Result:=-1;
if (Find='') or (StartPos>length(Source)) then exit;
Position:=StartPos;
repeat
// search first atom in find
FindPos:=1;
ReadNextPascalAtom(Find,FindPos,FindAtomStart);
FindAtom:=copy(Find,FindAtomStart,FindPos-FindAtomStart);
if FindAtom='' then exit;
if not CaseSensitive then FindAtom:=lowercase(FindAtom);
// search first atom in source
repeat
ReadNextPascalAtom(Source,Position,AtomStart);
SrcAtom:=copy(Source,AtomStart,Position-AtomStart);
if not CaseSensitive then SrcAtom:=lowercase(SrcAtom);
until (Position>length(Source)) or (SrcAtom=FindAtom);
if SrcAtom=FindAtom then begin
// first atom found
FirstSrcAtomStart:=AtomStart;
FirstSrcAtomEnd:=Position;
// compare the rest of Find
repeat
// get next atom in find
ReadNextPascalAtom(Find,FindPos,FindAtomStart);
FindAtom:=copy(Find,FindAtomStart,FindPos-FindAtomStart);
if FindAtom='' then break;
if not CaseSensitive then FindAtom:=lowercase(FindAtom);
// compare to next atom in source
ReadNextPascalAtom(Source,Position,AtomStart);
SrcAtom:=copy(Source,AtomStart,Position-AtomStart);
if not CaseSensitive then SrcAtom:=lowercase(SrcAtom);
until (SrcAtom<>FindAtom);
if (FindAtom='') and (FindAtomStart>length(Find)) then begin
// code found
Result:=FirstSrcAtomStart;
EndFoundPosition:=Position;
exit;
end;
end else begin
// first atom not found
exit;
end;
Position:=FirstSrcAtomEnd;
until false;
end;
procedure GetLineStartEndAtPosition(Source:string; Position:integer;
var LineStart,LineEnd:integer);
begin
LineStart:=Position;
while (LineStart>0) and (not (Source[LineStart] in [#10,#13])) do
dec(LineStart);
inc(LineStart);
LineEnd:=Position;
while (LineEnd<=length(Source)) and (not (Source[LineEnd] in [#10,#13])) do
inc(LineEnd);
end;
function ReadNextPascalAtom(Source:string; var Position,AtomStart:integer):string;
var DirectiveName:string;
DirStart,DirEnd,EndPos:integer;
begin
repeat
Result:=ReadRawNextPascalAtom(Source,Position,AtomStart);
if (copy(Result,1,2)='{$') or (copy(Result,1,3)='(*$') then begin
if copy(Result,1,2)='{$' then begin
DirStart:=3;
DirEnd:=length(Result);
end else begin
DirStart:=4;
DirEnd:=length(Result)-1;
end;
EndPos:=DirStart;
while (EndPos<DirEnd) and (Result[EndPos] in IdentifierChar) do inc(EndPos);
DirectiveName:=lowercase(copy(Result,DirStart,EndPos-DirStart));
if (length(DirectiveName)=1) and (Result[DirEnd] in ['+','-']) then begin
// switch
end else if (DirectiveName='i') or (DirectiveName='include') then begin
// include directive
break;
end;
// ToDo: compiler directives
end else
break;
until false;
end;
function ReadRawNextPascalAtom(Source:string;
var Position,AtomStart:integer):string;
var Len:integer;
c1,c2:char;
begin
Len:=length(Source);
// read til next atom
while (Position<=Len) do begin
case Source[Position] of
#0..#32: // spaces and special characters
begin
inc(Position);
end;
'{': // comment start or compiler directive
begin
if (Position<Len) and (Source[Position+1]='$') then
// compiler directive
break
else begin
// read till comment end
while (Position<=Len) and (Source[Position]<>'}') do inc(Position);
inc(Position);
end;
end;
'/': // comment or real division
if (Position<Len) and (Source[Position]='/') then begin
// comment start -> read til line end
inc(Position);
while (Position<=Len) and (not (Source[Position] in [#10,#13])) do
inc(Position);
end else
break;
'(': // comment, bracket or compiler directive
if (Position<Len) and (Source[Position]='*') then begin
if (Position+2<=Len) and (Source[Position]='$') then
// compiler driective
break
else begin
// comment start -> read til comment end
inc(Position,2);
while (Position<Len)
and ((Source[Position]<>'*') or (Source[Position]<>')')) do
inc(Position);
inc(Position,2);
end;
end else
// round bracket open
break;
else
break;
end;
end;
// read atom
AtomStart:=Position;
if Position<=Len then begin
c1:=Source[Position];
case c1 of
'a'..'z','A'..'Z','_': // identifier
begin
inc(Position);
while (Position<=Len) and (Source[Position] in IdentifierChar) do
inc(Position);
end;
'0'..'9': // number
begin
inc(Position);
// read numbers
while (Position<=Len) and (Source[Position] in ['0'..'9']) do
inc(Position);
if (Position<Len) and (Source[Position]='.') and (Source[Position]<>'.')
then begin
// real type number
inc(Position);
while (Position<=Len) and (Source[Position] in ['0'..'9']) do
inc(Position);
if (Position<=Len) and (Source[Position] in ['e','E']) then begin
// read exponent
inc(Position);
if (Position<=Len) and (Source[Position]='-') then inc(Position);
while (Position<=Len) and (Source[Position] in ['0'..'9']) do
inc(Position);
end;
end;
end;
'''': // string constant
begin
inc(Position);
while (Position<=Len) do begin
if Source[Position]='''' then begin
inc(Position);
if (Position<=Len) and (Source[Position]<>'''') then break;
end;
inc(Position);
end;
end;
'$': // hex constant
begin
inc(Position);
while (Position<=Len)
and (Source[Position] in ['0'..'9','A'..'F','a'..'f']) do
inc(Position);
end;
'{': // compiler directive
begin
inc(Position);
while (Position<=Len) and (Source[Position]<>'}') do
inc(Position);
inc(Position);
end;
'(': // bracket or compiler directive
if (Position<Len) and (Source[Position]='*') then begin
// compiler directive -> read til comment end
inc(Position,2);
while (Position<Len)
and ((Source[Position]<>'*') or (Source[Position]<>')')) do
inc(Position);
inc(Position,2);
end else
// round bracket open
inc(Position);
else
inc(Position);
if Position<=Len then begin
c2:=Source[Position];
// test for double char operator :=, +=, -=, /=, *=, <>, <=, >=, **, ..
if ((c2='=') and (c1 in [':','+','-','/','*','<','>']))
or ((c1='<') and (c2='>'))
or ((c1='.') and (c2='.'))
or ((c1='*') and (c2='*'))
then inc(Position);
end;
end;
end;
Result:=copy(Source,AtomStart,Position-AtomStart);
end;
end.

View File

@ -381,11 +381,28 @@ type
constructor Create(AOwner: TComponent); override;
end;
TLazSyntaxHighlighter =
(lshNone, lshText, lshFreePascal, lshDelphi, lshLFM, lshXML);
const
LazSyntaxHighlighterNames : array[TLazSyntaxHighlighter] of string = (
'None',
'Text',
'FreePascal',
'Delphi',
'LFM',
'XML'
);
var
EditorOptionsForm: TEditorOptionsForm;
EditorOpts: TEditorOptions;
function ShowEditorOptionsDialog:TModalResult;
function StrToLazSyntaxHighlighter(s: string): TLazSyntaxHighlighter;
function ExtensionToLazSyntaxHighlighter(Ext:string): TLazSyntaxHighlighter;
implementation
@ -404,6 +421,44 @@ begin
end;
end;
function StrToLazSyntaxHighlighter(s: string): TLazSyntaxHighlighter;
begin
for Result:=Low(TLazSyntaxHighlighter) to High(TLazSyntaxHighlighter) do
if (lowercase(s)=lowercase(LazSyntaxHighlighterNames[Result])) then exit;
Result:=lshFreePascal;
end;
function ExtensionToLazSyntaxHighlighter(Ext:string): TLazSyntaxHighlighter;
var s,CurExt:string;
StartPos,EndPos:integer;
begin
if (Ext='') then begin
Result:=lshNone;
exit;
end;
Ext:=lowercase(Ext);
if (Ext[1]='.') then Ext:=copy(Ext,2,length(Ext)-1);
s:=EditorOpts.SyntaxExtensions;
StartPos:=1;
while StartPos<=length(s) do begin
Endpos:=StartPos;
while (EndPos<=length(s)) and (s[EndPos]<>';') do inc(EndPos);
CurExt:=copy(s,Startpos,EndPos-StartPos);
if (CurExt<>'') and (CurExt[1]='.') then begin
CurExt:=copy(CurExt,2,length(CurExt)-1);
end;
if lowercase(CurExt)=Ext then begin
Result:=lshFreePascal;
if (Ext='.dpr') or (Ext='.dpk') or (Ext='.dfm') then Result:=lshDelphi;
exit;
end;
Startpos:=EndPos+1;
end;
if Ext='.xml' then Result:=lshXML
else if Ext='.lfm' then Result:=lshLFM
else if Ext='.txt' then Result:=lshText
else Result:=lshNone;
end;
const
EditOptsConfFileName = 'editoroptions.xml';
@ -663,9 +718,9 @@ begin
XMLConfig.SetValue('EditorOptions/Display/RightMargin',fRightMargin);
XMLConfig.SetValue('EditorOptions/Display/RightMarginColor',fRightMarginColor);
XMLConfig.SetValue('EditorOptions/Display/EditorFont',fEditorFont);
XMLConfig.GetValue('EditorOptions/Display/EditorFontHeight'
XMLConfig.SetValue('EditorOptions/Display/EditorFontHeight'
,fEditorFontHeight);
XMLConfig.GetValue('EditorOptions/Display/ExtraLineSpacing'
XMLConfig.SetValue('EditorOptions/Display/ExtraLineSpacing'
,fExtraLineSpacing);
// Key Mappings options

View File

@ -20,6 +20,22 @@ uses
type
//----------------------------------------------------------------------------
TBackupType = (
bakNone, // no backup files
bakSymbolInFront, // .~pp
bakSymbolBehind, // .pp~
bakCounter, // .pp;1
bakSameName, // .pp only available if backuping into subdirectory
bakUserDefinedAddExt // .pp.xxx
);
TBackupInfo = record
BackupType: TBackupType;
AdditionalExtension:string; // for bakUserDefinedAddExt
MaxCounter: integer; // for bakCounter
SubDirectory: string;
end;
{ class for storing environment options }
TEnvironmentOptions = class
private
@ -48,6 +64,13 @@ type
// object inspector
FObjectInspectorOptions: TOIOptions;
// backup
FBackupInfoRepositoryFiles: TBackupInfo;
FBackupInfoOtherFiles: TBackupInfo;
// recent files and directories
// ToDo
procedure SetFileName(NewFilename: string);
public
constructor Create;
@ -88,6 +111,12 @@ type
// object inspector
property ObjectInspectorOptions: TOIOptions
read FObjectInspectorOptions write FObjectInspectorOptions;
// backup
property BackupInfoRepositoryFiles: TBackupInfo
read FBackupInfoRepositoryFiles write FBackupInfoRepositoryFiles;
property BackupInfoOtherFiles: TBackupInfo
read FBackupInfoOtherFiles write FBackupInfoOtherFiles;
end;
//----------------------------------------------------------------------------
@ -199,6 +228,20 @@ begin
// object inspector
FObjectInspectorOptions:=TOIOptions.Create;
// backup
with FBackupInfoRepositoryFiles do begin
BackupType:=bakSameName;
AdditionalExtension:='bak'; // for bakUserDefinedAddExt
MaxCounter:=9; // for bakCounter
SubDirectory:='backup';
end;
with FBackupInfoOtherFiles do begin
BackupType:=bakUserDefinedAddExt;
AdditionalExtension:='bak'; // for bakUserDefinedAddExt
MaxCounter:=9; // for bakCounter
SubDirectory:='backup';
end;
end;
destructor TEnvironmentOptions.Destroy;
@ -242,6 +285,26 @@ var XMLConfig: TXMLConfig;
ARect.Bottom:=XMLConfig.GetValue(AKey+'/Bottom',ARect.Bottom);
end;
procedure LoadBackupInfo(var BackupInfo: TBackupInfo; Path:string);
var i:integer;
begin
with BackupInfo do begin
i:=XMLConfig.GetValue(Path+'Type',5);
case i of
0:BackupType:=bakNone;
1:BackupType:=bakSymbolInFront;
2:BackupType:=bakSymbolBehind;
3:BackupType:=bakCounter;
4:BackupType:=bakSameName;
else
BackupType:=bakUserDefinedAddExt;
end;
AdditionalExtension:=XMLConfig.GetValue(Path+'AdditionalExtension','bak');
MaxCounter:=XMLConfig.GetValue(Path+'MaxCounter',9);
SubDirectory:=XMLConfig.GetValue(Path+'SubDirectory','backup');
end;
end;
begin
try
XMLConfig:=TXMLConfig.Create(FFileName);
@ -281,9 +344,12 @@ begin
FGridSizeY:=XMLConfig.GetValue(
'EnvironmentOptions/FormEditor/GridSizeY',FGridSizeY);
if not OnlyDesktop then begin
// backup
LoadBackupInfo(FBackupInfoRepositoryFiles
,'EnvironmentOptions/BackupRepositoryFiles/');
LoadBackupInfo(FBackupInfoOtherFiles
,'EnvironmentOptions/BackupOtherFiles/');
end;
XMLConfig.Free;
@ -308,6 +374,26 @@ var XMLConfig: TXMLConfig;
XMLConfig.SetValue(AKey+'/Bottom',ARect.Bottom);
end;
procedure SaveBackupInfo(var BackupInfo: TBackupInfo; Path:string);
var i:integer;
begin
with BackupInfo do begin
case BackupType of
bakNone: i:=0;
bakSymbolInFront: i:=1;
bakSymbolBehind: i:=2;
bakCounter: i:=3;
bakSameName: i:=4;
else
i:=5; // bakUserDefinedAddExt;
end;
XMLConfig.SetValue(Path+'Type',i);
XMLConfig.SetValue(Path+'AdditionalExtension',AdditionalExtension);
XMLConfig.SetValue(Path+'MaxCounter',MaxCounter);
XMLConfig.SetValue(Path+'SubDirectory',SubDirectory);
end;
end;
begin
try
XMLConfig:=TXMLConfig.Create(FFileName);
@ -343,7 +429,11 @@ begin
XMLConfig.SetValue('EnvironmentOptions/FormEditor/GridSizeY',FGridSizeY);
if not OnlyDesktop then begin
// backup
SaveBackupInfo(FBackupInfoRepositoryFiles
,'EnvironmentOptions/BackupRepositoryFiles/');
SaveBackupInfo(FBackupInfoOtherFiles
,'EnvironmentOptions/BackupOtherFiles/');
end;
XMLConfig.Flush;

File diff suppressed because it is too large Load Diff

164
ide/newprojectdlg.pp Normal file
View File

@ -0,0 +1,164 @@
{
Author: Mattias Gaertner
Abstract:
The new project dialog for lazarus.
}
unit NewProjectDlg;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Graphics, Controls, LResources, Project, Buttons,
StdCtrls;
type
TNewProjectDialog = class(TForm)
CreateButton: TButton;
CancelButton: TButton;
ListBox: TListBox;
HelpLabel: TLabel;
procedure CreateButtonClick(Sender:TObject);
procedure CancelButtonClick(Sender:TObject);
procedure ListBoxMouseUp(Sender:TObject;
Button:TMouseButton; Shift:TShiftState; X,Y:integer);
private
procedure FillHelpLabel;
public
constructor Create(AOwner: TComponent); override;
end;
function ChooseNewProject(var ProjectType: TProjectType):TModalResult;
implementation
function ChooseNewProject(var ProjectType: TProjectType):TModalResult;
var NewProjectDialog: TNewProjectDialog;
i:integer;
pt:TProjectType;
begin
NewProjectDialog:=TNewProjectDialog.Create(Application);
try
Result:=NewProjectDialog.ShowModal;
if Result=mrOk then begin
i:=0;
for pt:=Low(TProjectType) to High(TProjectType) do begin
if i=NewProjectDialog.ListBox.ItemIndex then
ProjectType:=pt;
inc(i);
end;
end;
finally
NewProjectDialog.Free;
end;
end;
{ NewProjectDialog }
constructor TNewProjectDialog.Create(AOwner: TComponent);
var pt:TProjectType;
MaxX, MaxY:integer;
begin
inherited Create(AOwner);
if LazarusResources.Find(ClassName)=nil then begin
SetBounds((Screen.Width-300) div 2,(Screen.Height-250) div 2,390,240);
Caption:='Create a new project';
MaxX:=386;
MaxY:=238;
ListBox:=TListBox.Create(Self);
with ListBox do begin
Parent:=Self;
Name:='ListBox';
Left:=5;
Top:=5;
Width:=150;
Height:=MaxY-50;
with Items do begin
BeginUpdate;
for pt:=Low(TProjectType) to High(TProjectType) do
Add(ProjectTypeNames[pt]);
EndUpdate;
end;
ItemIndex:=0;
OnMouseUp:=@ListBoxMouseUp;
Show;
end;
HelpLabel:=TLabel.Create(Self);
with HelpLabel do begin
Parent:=Self;
Name:='HelpLabel';
Left:=ListBox.Left+ListBox.Width+10;
Top:=ListBox.Top+2;
Width:=MaxX-5-Left;
Height:=ListBox.Height-2;
WordWrap:=true;
Caption:='Select a project type';
Show;
end;
CreateButton:=TButton.Create(Self);
with CreateButton do begin
Parent:=Self;
Name:='CreateButton';
Width:=80;
Height:=23;
Left:=Self.ClientWidth-Width*2-2*15;
Top:=Self.ClientHeight-40;
OnClick:=@CreateButtonClick;
Caption:='Create';
Show;
end;
CancelButton:=TButton.Create(Self);
with CancelButton do begin
Parent:=Self;
Name:='CancelButton';
Width:=80;
Height:=23;
Left:=Self.ClientWidth-Width-15;
Top:=CreateButton.Top;
OnClick:=@CancelButtonClick;
Caption:='Cancel';
Show;
end;
end;
FillHelpLabel;
end;
procedure TNewProjectDialog.FillHelpLabel;
var i:integer;
pt:TProjectType;
begin
i:=0;
for pt:=Low(TProjectType) to High(TProjectType) do begin
if i=ListBox.ItemIndex then begin
HelpLabel.Caption:=ProjectTypeDescriptions[pt];
HelpLabel.Width:=ClientWidth-HelpLabel.Left-10;
end;
inc(i);
end;
end;
procedure TNewProjectDialog.CreateButtonClick(Sender:TObject);
begin
ModalResult:=mrOk;
end;
procedure TNewProjectDialog.CancelButtonClick(Sender:TObject);
begin
ModalResult:=mrCancel;
end;
procedure TNewProjectDialog.ListBoxMouseUp(Sender:TObject;
Button:TMouseButton; Shift:TShiftState; X,Y:integer);
begin
FillHelpLabel;
end;
end.

File diff suppressed because it is too large Load Diff

View File

@ -51,7 +51,6 @@ type
TNotifyFileEvent = procedure(Sender: Tobject; Filename : AnsiString) of Object;
{---- TSource Editor ---
TSourceEditor is the class that controls access the the Editor and the source
code. It creates the PopupMenu that appears when you right-click on the
@ -76,13 +75,11 @@ type
//Set during OPEN and Save
FFileName : AnsiString;
// Used GetModified like this -> Result := FEditor.Modified
FModified : Boolean;
FPopUpMenu : TPopupMenu;
//pulled out of the editor by getting it's TStrings
FSource : TStringList;
FSyntaxHighlighterType: TLazSyntaxHighlighter;
//set on OPEN/SAVE
FUnitName : String;
@ -106,6 +103,7 @@ type
Procedure SetCurrentCursorYLine(num : Integer);
Function GetAncestor : String;
Function GetModified : Boolean;
procedure SetModified(NewValue:boolean);
Function GetInsertMode : Boolean;
Function GetReadonly : Boolean;
Function TextUnderCursor : String;
@ -119,6 +117,8 @@ type
Procedure CreateEditor(AOwner : TComponent; AParent: TWinControl);
Procedure CreateFormFromUnit;
protected
FindText : String;
ErrorMsgs : TStrings;
Procedure DisplayControl;
Procedure ReParent(AParent : TWinControl);
@ -128,21 +128,17 @@ type
var AChar: char; Data: pointer);
Procedure CommandProcessed(Sender: TObject; var Command: TSynEditorCommand;
var AChar: char; Data: pointer);
Procedure FocusEditor; // called by TSourceNotebook whne the Notebook page
// changes so the editor is focused
Procedure EditorStatusChanged(Sender: TObject; Changes: TSynStatusChanges);
Procedure ccOnTimer(sender : TObject);
Procedure ccAddMessage(Texts : String);
Function ccParse(Texts : String) : TStrings;
Procedure FocusEditor; // called by TSourceNotebook whne the Notebook page
// changes so the editor is focused
Procedure EditorStatusChanged(Sender: TObject; Changes: TSynStatusChanges);
Function RefreshEditorSettings : Boolean;
procedure SetSyntaxHighlighterType(ASyntaxHighlighterType: TLazSyntaxHighlighter);
property Visible : Boolean read FVisible write FVisible default False;
FindText : String;
ErrorMsgs : TStrings;
public
constructor Create(AOwner : TComponent; AParent : TWinControl);
destructor Destroy; override;
@ -170,15 +166,17 @@ type
read GetCurrentCursorYLine write SetCurrentCursorYLine;
property Owner : TComponent read FAOwner;
property Source : TStrings read GetSource write SetSource;
property UnitName : String read FUnitName write FUnitname;
property UnitName : String read FUnitName write fUnitname;
property FileName : AnsiString read FFileName write FFilename;
property Modified : Boolean read GetModified;
property Modified : Boolean read GetModified write SetModified;
property ReadOnly : Boolean read GetReadOnly;
property InsertMode : Boolean read GetInsertmode;
property CodeTemplates: SynEditAutoComplete.TSynAutoComplete
read FCodeTemplates write SetCodeTemplates;
property PopupMenu:TPopupMenu read FPopUpMenu write SetPopUpMenu;
property EditorComponent:TSynEdit read FEditor;
property SyntaxHighlighterType: TLazSyntaxHighlighter
read fSyntaxHighlighterType write SetSyntaxHighlighterType;
property OnAfterClose : TNotifyEvent read FOnAfterClose write FOnAfterClose;
property OnBeforeClose : TNotifyEvent read FOnBeforeClose write FOnBeforeClose;
@ -192,16 +190,21 @@ type
TSourceNotebook = class(TFORM)
private
FMainIDE : TComponent;
FFormEditor : TFormEditor;
FCodeTemplateModul : SynEditAutoComplete.TSynAutoComplete;
FSourceEditorList : TList; // list of TSourceEditor
FSaveDialog : TSaveDialog;
FOpenDialog : TOpenDialog;
FOnOpenFile : TNotifyFileEvent;
FOnCloseFile : TNotifyFileEvent;
FOnSaveFile : TNotifyFileEvent;
FMainIDE : TComponent;
FCodeTemplateModul : SynEditAutoComplete.TSynAutoComplete;
Function GetEmpty : Boolean; //look at the # of pages
FOnNewClicked : TNotifyEvent;
FOnOpenClicked : TNotifyEvent;
FOnOpenFileAtCursorClicked : TNotifyEvent;
FOnCloseClicked : TNotifyEvent;
FOnSaveClicked : TNotifyEvent;
FOnSaveAsClicked : TNotifyEvent;
FOnSaveAllClicked : TNotifyEvent;
// PopupMenu
Procedure BuildPopupMenu;
@ -218,7 +221,6 @@ type
ccSelection : String;
Function CreateNotebook : Boolean;
Function GetActiveSE : TSourceEditor;
Function DisplayPage(SE : TSourceEditor) : Boolean;
Function NewSE(Pagenum : Integer) : TSourceEditor;
Procedure EditorChanged(sender : TObject);
@ -244,6 +246,8 @@ type
property Editors[Index:integer]:TSourceEditor read GetEditors;
function EditorCount:integer;
function FindSourceEditorWithPageIndex(PageIndex:integer):TSourceEditor;
Function GetActiveSE : TSourceEditor;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
@ -269,7 +273,8 @@ type
procedure ReplaceClicked(Sender : TObject);
procedure FindAgainClicked(Sender : TObject);
Procedure NewFile(UnitName: String; Source : TStrings; aVisible : Boolean);
Procedure NewFile(UnitName: String; Source : TStrings);
Procedure CloseFile(PageIndex:integer);
Procedure OpenFile(FileName: String; aVisible : Boolean);
Procedure ToggleBookmark(Value : Integer);
@ -282,18 +287,25 @@ type
AnEditor: TCustomSynEdit; var Index:integer);
procedure OnWordCompletionGetSource(var Source:TStrings; SourceIndex:integer);
property Empty : Boolean read GetEmpty;
function Empty: boolean;
property FormEditor : TFormEditor read FFormEditor write FFormEditor;
property MainIDE : TComponent read FMainIDE;
published
Notebook1 : TNotebook;
Notebook : TNotebook;
SrcPopUpMenu : TPopupMenu;
StatusBar : TStatusBar;
ToggleMenuItem : TMenuItem;
Procedure NoteBookPageChanged(Sender : TObject);
property OnCloseFile : TNotifyFileEvent read FOnCloseFile write FOnCloseFile;
property OnOpenFile : TNotifyFileEvent read FOnOPenFile write FOnOpenFile;
property OnSaveFile : TNotifyFileEvent read FOnSaveFile write FOnSaveFile;
Procedure NotebookPageChanged(Sender : TObject);
property OnNewClicked : TNotifyEvent read FOnNewClicked write FOnNewClicked;
property OnOpenClicked : TNotifyEvent read FOnOPenClicked write FOnOpenClicked;
property OnOpenFileAtCursorClicked : TNotifyEvent
read FOnOpenFileAtCursorClicked write FOnOpenFileAtCursorClicked;
property OnCloseClicked : TNotifyEvent read FOnCloseClicked write FOnCloseClicked;
property OnSaveClicked : TNotifyEvent read FOnSaveClicked write FOnSaveClicked;
property OnSaveAsClicked : TNotifyEvent
read FOnSaveAsClicked write FOnSaveAsClicked;
property OnSaveAllClicked : TNotifyEvent
read FOnSaveAllClicked write FOnSaveAllClicked;
end;
{Goto dialog}
@ -333,15 +345,19 @@ var
and the AParent is usually a page of a @link(TNotebook)
}
constructor TSourceEditor.create(AOwner : TComponent; AParent : TWinControl);
constructor TSourceEditor.Create(AOwner : TComponent; AParent : TWinControl);
Begin
writeln('TSourceEditor.create 1');
inherited Create;
FAOwner := AOwner;
FSource := TStringList.create;
FSource := TStringList.Create;
FSyntaxHighlighterType:=lshNone;
FControl := nil;
writeln('TSourceEditor.create 2');
CreateEditor(AOwner,AParent);
writeln('TSourceEditor.create end');
end;
destructor TSourceEditor.destroy;
@ -458,16 +474,16 @@ Begin
end;
Procedure TSourceEditor.OpenAtCursorClicked(Sender : TObject);
var
{var
Texts : String;
Found : Boolean;
SearchDir : String;
AppDIr : String;
TempDir : String;
Num : Integer;
DirDelimiter : Char;
DirDelimiter : Char;}
Begin
Texts := TextunderCursor;
{ Texts := TextunderCursor;
if Length(Texts) <= 1 then Exit;
Found := False;
@ -536,6 +552,7 @@ Begin
If not Found then
Application.MessageBox('File not found','Error',MB_OK);
}
end;
procedure TSourceEditor.GetDialogPosition(Width, Height:integer;
@ -767,17 +784,29 @@ Begin
OnEditorChange(sender);
end;
procedure TSourceEditor.SetSyntaxHighlighterType(
ASyntaxHighlighterType: TLazSyntaxHighlighter);
begin
if EditorOPts.UseSyntaxHighlight then begin
case ASyntaxHighlighterType of
lshFreePascal,lshDelphi:
FEditor.Highlighter:=aHighlighter;
else
FEditor.Highlighter:=nil;
end;
end else FEditor.Highlighter:=nil;
if ASyntaxHighlighterType<>fSyntaxHighlighterType then begin
fSyntaxHighlighterType:=ASyntaxHighlighterType;
end;
end;
Function TSourceEditor.RefreshEditorSettings : Boolean;
Begin
Result := False;
if EditorOPts.UseSyntaxHighlight then
Begin
EditorOPts.GetHighlighterSettings(aHighlighter);
FEditor.Highlighter:=aHighlighter;
end
else
FEditor.Highlighter:=nil;
EditorOpts.GetHighlighterSettings(aHighlighter);
SetSyntaxHighlighterType(fSyntaxHighlighterType);
EditorOpts.GetSynEditSettings(FEditor);
end;
@ -793,7 +822,7 @@ Begin
Result := '';
Found := False;
DirDelimiter := '/';
SearchDir := TSourceNoteBook(Owner).SearchPaths;
SearchDir := TSourceNotebook(Owner).SearchPaths;
Writeln('Searcvhdir is '+Searchdir);
Num := pos(';',SearchDir);
While (not Found) and (SearchDir <> '') do
@ -925,8 +954,10 @@ End;
Procedure TSourceEditor.CreateEditor(AOwner : TComponent; AParent: TWinControl);
Begin
if assigned(FEditor) then Begin
writeln('TSourceEditor.CreateEditor freeing old FEditor');
FSource.Assign(FEditor.Lines);
FEditor.Free;
FEditor:=nil;
dec(Editor_num);
end;
@ -946,7 +977,9 @@ Begin
RefreshEditorSettings;
aCompletion.AddEditor(FEditor);
FEditor.Lines.Assign(FSource);
writeln('TSourceEditor.CreateEditor focusing');
FEditor.SetFocus;
writeln('TSourceEditor.CreateEditor end');
end;
Procedure TSourceEditor.AddControlCode(_Control : TComponent);
@ -958,14 +991,12 @@ var
TempSource : TStringList;
Ancestor : String;
begin
Writeln('**********************************************************');
TempSource := TStringList.Create;
TempSource.Assign(Source);
//get the control name
PI := _Control.ClassInfo;
nmControlType := PI^.Name;
nmControlType := Uppercase(nmControlType[1]+nmControlType[2])+Lowercase(Copy(nmControlType,3,length(nmControlType)));
Ancestor := GetAncestor;
Ancestor := 'TFORM';
@ -979,7 +1010,7 @@ For I := 0 to TempSource.Count-1 do
Writeln('Ancestor is '+Ancestor);
Writeln('TWinControl(_Control.Owner).Name is '+TWinControl(_Control.Owner).Name);
Writeln('Line is '+TempSource.Strings[i]);
if (pos(uppercase(Ancestor),uppercase(TempSource.Strings[i])) <> 0)
if (pos(Ancestor,TempSource.Strings[i]) <> 0)
and (pos(lowercase(TWinControl(_Control.Owner).Name),
lowercase(TempSource.Strings[i])) <> 0)
and (pos('CLASS',Uppercase(TempSource.Strings[i])) <> 0) then
@ -992,7 +1023,7 @@ For I := 0 to TempSource.Count-1 do
Begin
//alphabetical
inc(i);
NewSource := uppercase(_Control.Name[1])+lowercase(Copy(_Control.Name,2,length(_Control.Name)))+' : '+nmControlType+';';
NewSource := _Control.Name+' : '+nmControlType+';';
// Here I decide if I need to try and insert the control's text code in any certain order.
//if there's no controls then I just insert it, otherwise...
@ -1000,7 +1031,7 @@ For I := 0 to TempSource.Count-1 do
while NewSource > (trim(TempSource.Strings[i])) do
inc(i);
TempSource.Insert(i,' '+NewSource);
TempSource.Insert(i,' '+NewSource);
end;
@ -1068,7 +1099,7 @@ end;
Function TSourceEditor.GetSource : TStrings;
Begin
//return mwedit's source.
//return synedit's source.
Result := FEditor.Lines;
end;
@ -1112,7 +1143,12 @@ end;
Function TSourceEditor.GetModified : Boolean;
Begin
Result := FEditor.Modified;
Result := FEditor.Modified;
end;
procedure TSourceEditor.SetModified(NewValue:boolean);
begin
FEditor.Modified:=NewValue;
end;
Function TSourceEditor.GetInsertMode : Boolean;
@ -1147,8 +1183,7 @@ Begin
try
Add('unit '+FUnitName+';');
Add('');
Add('{$mode objfpc}');
Add('{$H+}');
Add('{$mode objfpc}{$H+}');
Add('');
Add('interface');
Add('');
@ -1236,7 +1271,6 @@ Writeln('[TSourceEditor] Open');
try
FEditor.Lines.LoadFromFile(FileName);
FModified := False;
FUnitName := ExtractFileName(Filename);
//remove extension
if pos('.',FUnitname) <> 0 then
@ -1254,65 +1288,13 @@ end;
Function TSourceEditor.Save : Boolean;
var
s : TStringList;
I,X : Integer;
Texts : String;
NewUnitName : String;
Found : Boolean;
Begin
Result := True;
If Assigned(FOnBeforeSave) then FOnBeforeSave(Self);
try
//change the unitname
Found := False;
S := TStringList.Create;
S.Assign(FEditor.Lines);
I := 0;
NewUnitName := ExtractFileName(FileName); //in case there is a path
If ExtractFileExt(FileName) <> '' then
NewUnitName := Copy(NewUnitName,1,length(NewUnitName)-length(ExtractFileExt(Filename)));
While I < S.Count do
Begin
Texts := S.Strings[i];
Writeln('Texts = '+Texts);
if (pos('unit',lowercase(texts)) <> 0) and
(pos(lowercase(unitname)+';',Lowercase(texts)) <> 0) then
Begin
X := pos(lowercase(unitname)+';',Lowercase(texts));
delete(Texts,x,length(unitname));
insert(NewUnitName,Texts,x);
S.Strings[i] := Texts;
Found := True;
Break;
end;
inc(i);
end;
if Found then
Begin
I := 0;
While I < S.Count do
Begin
Texts := S.Strings[i];
if pos(lowercase(format('{$I %s.lrc}',[UnitName])),lowercase(Texts)) <> 0 then
Begin
X := pos(lowercase(format('{$I %s.lrc}',[UnitName])),Lowercase(Texts));
delete(Texts,x,length(format('{$I %s.lrc}',[UnitName])));
insert(format('{$I %s.lrc}',[NewUnitName]),Texts,x);
S.Strings[i] := Texts;
break;
end;
inc(i);
end;
FEditor.Lines.Assign(s);
end;
FEditor.Lines.SaveToFile(FileName);
FEditor.Modified := False;
UnitName := NewUnitName;
except
Result := False;
end;
@ -1826,21 +1808,21 @@ End;
Function TSourceNotebook.CreateNotebook : Boolean;
Begin
Result := False;
if not assigned(Notebook1) then
if not assigned(Notebook) then
Begin
Result := True;
Notebook1 := TNotebook.Create(self);
with Notebook1 do
Notebook := TNotebook.Create(self);
with Notebook do
Begin
Parent := Self;
Align := alClient;
Left := 0;
Top :=2;
Width := ClientWidth;
Height := ClientHeight-Notebook1.top;
Height := ClientHeight-Notebook.top;
Pages.Strings[0] := 'unit1';
PageIndex := 0; // Set it to the first page
OnPageChanged := @NoteBookPageChanged;
OnPageChanged := @NotebookPageChanged;
Show;
end; //with
Show; //used to display the code form
@ -1848,7 +1830,7 @@ Begin
end;
End;
Procedure TSourceNoteBook.BuildPopupMenu;
Procedure TSourceNotebook.BuildPopupMenu;
Function Seperator : TMenuItem;
Begin
@ -1950,8 +1932,8 @@ Var
Notebook_Just_Created : Boolean;
begin
Notebook_Just_Created := (not assigned(Notebook1)) or
(Notebook1.Pages.Count = 0);
Notebook_Just_Created := (not assigned(Notebook)) or
(Notebook.Pages.Count = 0);
if Notebook_Just_Created then
TempSourceEditor := NewSe(0)
@ -1960,7 +1942,7 @@ begin
TempSourceEditor.CreateFormUnit(AForm);
Notebook1.Pages.Strings[Notebook1.PageIndex] := TempSourceEditor.Unitname;
Notebook.Pages.Strings[Notebook.PageIndex] := TempSourceEditor.Unitname;
Result := TempSourceEditor;
Show;
@ -1972,35 +1954,26 @@ Begin
End;
Function TSourceNotebook.NewSe(PageNum : Integer) : TSourceEditor;
var
UnitIndex,I:integer;
Begin
UnitIndex := 0;
writeln('TSourceNotebook.NewSe 1');
if CreateNotebook then Pagenum := 0;
if Pagenum = -1 then begin //add a new page
repeat
inc(UnitIndex);
I:=FSourceEditorList.Count-1;
while (I>=0)
and (lowercase(TSourceEditor(FSourceEditorList[I]).UnitName)
<>'unit'+IntToStr(UnitIndex)) do begin
writeln('[TSourceNotebook.NewSe] I=',I,' unitname='
,lowercase(TSourceEditor(FSourceEditorList[I]).UnitName));
dec(I);
end;
until I<0;
Pagenum := Notebook1.Pages.Add('unit'+IntToStr(UnitIndex));
writeln('TSourceNotebook.NewSe 2');
if Pagenum < 0 then begin //add a new page right to the current
Pagenum := Notebook.PageIndex+1;
Notebook.Pages.Insert(PageNum,FindUniquePageName('',-1));
end;
Result := TSourceEditor.Create(Self,Notebook1.Page[PageNum]);
Result.FUnitName:=Notebook1.Pages[PageNum];
writeln('TSourceNotebook.NewSe 3');
Result := TSourceEditor.Create(Self,Notebook.Page[PageNum]);
writeln('TSourceNotebook.NewSe 4');
Result.FUnitName:=Notebook.Pages[PageNum];
Result.CodeTemplates:=CodeTemplateModul;
Notebook1.PageIndex := Pagenum;
Notebook.PageIndex := Pagenum;
FSourceEditorList.Add(Result);
Result.EditorComponent.BookMarkOptions.BookmarkImages := Bookmarks;
Result.PopupMenu:=SrcPopupMenu;
Result.OnEditorChange := @EditorChanged;
writeln('TSourceNotebook.NewSe END');
writeln('TSourceNotebook.NewSe end');
end;
Procedure TSourceNotebook.DisplayCodeforControl(Control : TObject);
@ -2052,9 +2025,9 @@ Var
Begin
Result := False;
for X := 0 to Notebook1.Pages.Count-1 do
for X := 0 to Notebook.Pages.Count-1 do
Begin
With Notebook1.Page[X] do
With Notebook.Page[X] do
for I := 0 to ControlCount-1 do
if Controls[I] is TmwCustomEdit then
Begin
@ -2070,9 +2043,9 @@ Begin
if SE.EditorComponent = TempEditor then
Begin
Notebook1.PageIndex := X;
Notebook.PageIndex := X;
//Bringtofront does not work yet.
//Notebook1.BringToFront;
//Notebook.BringToFront;
//so I hide it and unhide it.
Visible := False;
Visible := True;
@ -2080,25 +2053,22 @@ Begin
end
else
Begin //the SE isn't on a page so we need to create a page for it.
Notebook1.PageIndex := Notebook1.Pages.Add(SE.UnitName);
SE.ReParent(Notebook1.Page[Notebook1.Pageindex]);
Notebook.PageIndex := Notebook.Pages.Add(SE.UnitName);
SE.ReParent(Notebook.Page[Notebook.Pageindex]);
end;
end;
Function TSourceNotebook.GetActiveSE : TSourceEditor;
Var
I,X : Integer;
function TSourceNotebook.FindSourceEditorWithPageIndex(
PageIndex:integer):TSourceEditor;
var I:integer;
TempEditor : TControl;
Begin
begin
Result := nil;
if (FSourceEditorList=nil)
or (NoteBook1=nil) or (NoteBook1.PageIndex<0) then exit;
X := FSourceEditorList.Count;
if X = 0 then Exit;
or (Notebook=nil)
or (PageIndex<0) or (PageIndex>Notebook.Pages.Count) then exit;
TempEditor:=nil;
with Notebook1.Page[Notebook1.PageIndex] do
with Notebook.Page[PageIndex] do
for I := 0 to ControlCount-1 do
if Controls[I] is TmwCustomEdit then
Begin
@ -2106,62 +2076,45 @@ Begin
Break;
end;
if TempEditor=nil then exit;
// TempEditor now is the editor on the active page
// Compare it to the editor help by the SourceEditors
I := FSourceEditorList.Count-1;
while (I>=0)
and (TSourceEditor(FSourceEditorList[I]).EditorComponent <> TempEditor) do
dec(i);
if i<0 then exit;
Result := TSourceEditor(FSourceEditorList[i]);
end;
Function TSourceNotebook.GetEmpty : Boolean;
Function TSourceNotebook.GetActiveSE : TSourceEditor;
Begin
Result := (not assigned(Notebook1)) or (Notebook1.Pages.Count = 0);
Result := nil;
if (FSourceEditorList=nil) or (FSourceEditorList.Count=0)
or (Notebook=nil) or (Notebook.PageIndex<0) then exit;
Result:= FindSourceEditorWithPageIndex(Notebook.PageIndex);
end;
Function TSourceNotebook.Empty : Boolean;
Begin
Result := (not assigned(Notebook)) or (Notebook.Pages.Count = 0);
end;
Procedure TSourceNotebook.NextEditor;
Begin
if Notebook1.PageIndex < Notebook1.PAges.Count-1 then
Notebook1.PAgeindex := Notebook1.Pageindex+1;
if Notebook.PageIndex < Notebook.Pages.Count-1 then
Notebook.Pageindex := Notebook.Pageindex+1;
End;
Procedure TSourceNotebook.PrevEditor;
Begin
if Notebook1.PageIndex > 0 then
Notebook1.PAgeindex := Notebook1.Pageindex-1;
if Notebook.PageIndex > 0 then
Notebook.Pageindex := Notebook.Pageindex-1;
End;
Procedure TSourceNotebook.OpenClicked(Sender: TObject);
Var
TempEditor : TSourceEditor;
Begin
FOpenDialog.Title := 'Open';
if FOpenDialog.Execute then Begin
//create a new page
Writeln('create a new editor');
TempEditor := NewSE(-1);
Writeln('Done create a new editor');
TempEditor.Filename := FOpenDialog.Filename;
if (TempEditor.Open) then
Begin
Writeln('1');
if assigned(FOnOpenFile) then
FOnOpenFile(TObject(TempEditor),FOpenDialog.Filename);
Writeln('2');
Notebook1.Pages.Strings[Notebook1.Pageindex] :=
TempEditor.UnitName;
Writeln('3');
end;
TempEditor.Visible := True;
UpdateStatusBar;
end;
if Assigned(FOnOpenClicked) then FOnOpenClicked(Sender);
end;
Procedure TSourceNotebook.FindClicked(Sender : TObject);
@ -2228,11 +2181,9 @@ begin
end;
Procedure TSourceNotebook.OpenAtCursorClicked(Sender : TObject);
var
ActEdit:TSourceEditor;
begin
ActEdit:=GetActiveSE;
ActEdit.OpenAtCursorClicked(Sender);
if Assigned(FOnOpenFileAtCursorClicked) then
FOnOpenFileAtCursorClicked(Sender);
end;
Procedure TSourceNotebook.BookMarkToggle(Value : Integer);
@ -2267,11 +2218,11 @@ End;
Procedure TSourceNotebook.BookMarkGoto(Value : Integer);
var AnEditor:TSourceEditor;
begin
if NoteBook1=nil then exit;
if Notebook=nil then exit;
AnEditor:=FindBookmark(Value);
if AnEditor<>nil then begin
AnEditor.EditorComponent.GotoBookMark(Value);
NoteBook1.PageIndex:=FindPageWithEditor(AnEditor);
Notebook.PageIndex:=FindPageWithEditor(AnEditor);
end;
end;
@ -2281,23 +2232,46 @@ begin
BookMarkGoTo(Value);
End;
Procedure TSourceNotebook.NewFile(UnitName: String; Source : TStrings;
aVisible : Boolean);
Procedure TSourceNotebook.NewFile(UnitName: String; Source : TStrings);
Var
TempEditor : TSourceEditor;
Begin
//create a new page
writeln('[TSourceNotebook.NewFile] 1');
TempEditor := NewSE(-1);
writeln('[TSourceNotebook.NewFile] 2');
TempEditor.Unitname := Unitname;
TempEditor.Source := Source;
if Visible then
Notebook1.Pages.Strings[Notebook1.Pageindex] := TempEditor.UnitName;
TempEditor.Visible := aVisible;
writeln('[TSourceNotebook.NewFile] 3');
Notebook.Pages[Notebook.PageIndex] :=
FindUniquePageName(UnitName,Notebook.PageIndex);
writeln('[TSourceNotebook.NewFile] end');
end;
Procedure TSourceNotebook.CloseFile(PageIndex:integer);
var TempEditor: TSourceEditor;
Begin
writeln('TSourceNotebook.CloseFile 1 PageIndex=',PageIndex);
TempEditor:= FindSourceEditorWithPageIndex(PageIndex);
if TempEditor=nil then exit;
TempEditor.Close;
FSourceEditorList.Remove(TempEditor);
TempEditor.Free;
writeln('TSourceNotebook.CloseFile 2 PageCount=',Notebook.Pages.Count);
if Notebook.Pages.Count>1 then begin
Notebook.Pages.Delete(PageIndex);
UpdateStatusBar;
end else begin
Notebook.Free;
Notebook:=nil;
Hide;
end;
writeln('TSourceNotebook.CloseFile end');
end;
Procedure TSourceNotebook.OpenFile(FileName: String; aVisible : Boolean);
Var
TempEditor : TSourceEditor;
TempEditor : TSourceEditor;
Begin
if FileExists(Filename) then
begin
@ -2305,12 +2279,10 @@ Begin
TempEditor := NewSE(-1);
TempEditor.Filename := Filename;
if (TempEditor.OPen) then
if (TempEditor.Open) then
Begin
if assigned(FOnOPenFile) then
FOnOpenFile(TObject(TempEditor),FOpenDialog.Filename);
if Visible then
Notebook1.Pages.Strings[Notebook1.Pageindex] :=
Notebook.Pages.Strings[Notebook.Pageindex] :=
ExtractFileName(TempEditor.UnitName);
TempEditor.Visible := aVisible;
end;
@ -2319,29 +2291,13 @@ Begin
end;
Procedure TSourceNotebook.NewClicked(Sender: TObject);
Var
TempEditor : TSourceEditor;
Begin
//create a new page
TempEditor := NewSE(-1);
TempEditor.CreateNewUnit;
TempEditor.Visible := True;
UpdateStatusBar;
Show;
if Assigned(FOnNewClicked) then FOnNewClicked(Sender);
End;
Procedure TSourceNotebook.SaveClicked(Sender: TObject);
Begin
if ActiveFileName <> '' then
begin
if (GetActiveSE.Save) then
if assigned(FOnSaveFile) then
FOnSaveFile(TObject(GetActiveSE),ActiveFilename)
end
else
SaveAsClicked(Sender);
UpdateStatusBar;
if Assigned(FOnSaveClicked) then FOnSaveClicked(Sender);
end;
Function TSourceNotebook.ActiveUnitName : String;
@ -2366,29 +2322,8 @@ begin
end;
Procedure TSourceNotebook.CloseClicked(Sender : TObject);
var TempEditor: TSourceEditor;
Begin
TempEditor:=GetActiveSE;
if TempEditor=nil then exit;
if (TempEditor.Modified) then
If Application.MessageBox('Source has changed. Save now?'
,'Warning',mb_YesNo) = mrYes then
SaveClicked(Sender);
if (TempEditor.Close) then
if assigned(FOnCloseFile) then begin
FOnCloseFile(Self,ActiveFilename);
end;
if NoteBook1.Pages.Count>1 then begin
Notebook1.Pages.Delete(Notebook1.PageIndex);
UpdateStatusBar;
end else begin
Notebook1.Free;
NoteBook1:=nil;
Hide;
end;
FSourceEditorList.Delete(FSourceEditorList.IndexOf(TempEditor));
TempEditor.Free;
if Assigned(FOnCloseClicked) then FOnCloseClicked(Sender);
end;
Function TSourceNotebook.FindUniquePageName(FileName:string;
@ -2400,10 +2335,10 @@ var I:integer;
var a:integer;
begin
Result:=false;
if NoteBook1=nil then exit;
for a:=0 to NoteBook1.Pages.Count-1 do begin
if Notebook=nil then exit;
for a:=0 to Notebook.Pages.Count-1 do begin
if (a<>IgnorePageIndex)
and (lowercase(NoteBook1.Pages[a])=lowercase(AName)) then begin
and (lowercase(Notebook.Pages[a])=lowercase(AName)) then begin
Result:=true;
exit;
end;
@ -2411,7 +2346,14 @@ var I:integer;
end;
begin
if FileName='' then FileName:='unit';
if FileName='' then begin
FileName:='unit1';
if not PageNameExists(FileName) then begin
Result:=Filename;
exit;
end;
FileName:='unit1';
end;
ShortName:=ExtractFileName(FileName);
Ext:=ExtractFileExt(ShortName);
if (Ext='.pp') or (Ext='.pas') then
@ -2427,63 +2369,13 @@ begin
end;
Procedure TSourceNotebook.SaveAsClicked(Sender : TObject);
var TempEditor: TSourceEditor;
AText,ACaption:AnsiString;
Begin
TempEditor:=GetActiveSE;
if TempEditor=nil then exit;
FSaveDialog.Title := 'Save '+ActiveUnitName+' as :';
if ActiveFileName <> '' then
FSaveDialog.Filename := ActiveFileName
else
FSaveDialog.Filename := ActiveUnitName+'.pp';
if FSaveDialog.Execute then
begin
if FileExists(FSaveDialog.Filename) then begin
ACaption:='Overwrite?';
AText:='File "'+FSaveDialog.Filename+'" exists. Overwrite?';
if Application.MessageBox(PChar(AText),PChar(ACaption),mb_YesNo)=mrNo then
exit;
end;
TempEditor.FileName := FSaveDialog.Filename;
NoteBook1.Pages[NoteBook1.PageIndex]:=
FindUniquePageName(TempEditor.FileName,NoteBook1.PageIndex);
if (TempEditor.Save) then
if assigned(FOnSaveFile) then
FOnSaveFile(TObject(TempEditor),ActiveFilename);
end
else
Exit;
if Assigned(FOnSaveAsClicked) then FOnSaveAsClicked(Sender);
end;
Procedure TSourceNotebook.SaveAllClicked(Sender : TObject);
Var
I : Integer;
TempEditor : TSourceEditor;
Begin
For I := 0 to FSourceEditorList.Count-1 do
Begin
TempEditor := TSourceEditor(FSourceEditorList.Items[i]);
if TempEditor.Visible then
Begin
FSaveDialog.Title := 'Save '+TempEditor.UnitName+' as :';
if TempEditor.FileName <> '' then
FSaveDialog.Filename := TempEditor.FileName
else
FSaveDialog.Filename := TempEditor.UnitName+'.pp';
if FSaveDialog.Execute then
begin
TempEditor.FileName := FSaveDialog.Filename;
if (TempEditor.Save) then
if assigned(FOnSaveFile) then
FOnSaveFile(TObject(TempEditor),TempEditor.FileName);
end
else
Break;
end;
end;
if Assigned(FOnSaveAllClicked) then FOnSaveAllClicked(Sender);
end;
Function TSourceNotebook.GetSourceForUnit(UnitName : String) : TStrings;
@ -2567,15 +2459,15 @@ begin
Result:=nil;
end;
function TSourceNoteBook.FindPageWithEditor(ASourceEditor: TSourceEditor):integer;
function TSourceNotebook.FindPageWithEditor(ASourceEditor: TSourceEditor):integer;
var i:integer;
begin
if NoteBook1=nil then begin
if Notebook=nil then begin
Result:=-1;
end else begin
Result:=NoteBook1.Pages.Count-1;
Result:=Notebook.Pages.Count-1;
while (Result>=0) do begin
with Notebook1.Page[Result] do
with Notebook.Page[Result] do
for I := 0 to ControlCount-1 do
if Controls[I]=TControl(ASourceEditor) then exit;
dec(Result);
@ -2583,7 +2475,7 @@ begin
end;
end;
Procedure TSourceNotebook.NoteBookPageChanged(Sender : TObject);
Procedure TSourceNotebook.NotebookPageChanged(Sender : TObject);
var TempEditor:TSourceEditor;
Begin
TempEditor:=GetActiveSE;
@ -2620,8 +2512,8 @@ begin
end;
ecGotoEditor1..ecGotoEditor9,ecGotoEditor0:
if NoteBook1.Pages.Count>Command-ecGotoEditor1 then
NoteBook1.PageIndex:=Command-ecGotoEditor1;
if Notebook.Pages.Count>Command-ecGotoEditor1 then
Notebook.PageIndex:=Command-ecGotoEditor1;
end; //case
end;