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/toolbar.pp svneol=native#text/pascal
examples/trackbar.pp svneol=native#text/pascal examples/trackbar.pp svneol=native#text/pascal
ide/codetemplatedialog.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/compiler.pp svneol=native#text/pascal
ide/compileroptions.pp svneol=native#text/pascal ide/compileroptions.pp svneol=native#text/pascal
ide/compreg.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/lazconf.pp svneol=native#text/pascal
ide/lazres.pp svneol=native#text/pascal ide/lazres.pp svneol=native#text/pascal
ide/main.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/project.pp svneol=native#text/pascal
ide/splash.pp svneol=native#text/pascal ide/splash.pp svneol=native#text/pascal
ide/testform.pp svneol=native#text/pascal ide/testform.pp svneol=native#text/pascal

View File

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

View File

@ -115,8 +115,15 @@ begin
if CompTableSensitive <> Sensitive then if CompTableSensitive <> Sensitive then
begin begin
CompTableSensitive := Sensitive; 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); for I := #0 to #255 do CompTable[I] := ord(I);
if not Sensitive then CharLowerBuff(PChar(@CompTable[#0]), 256); if not Sensitive then CharLowerBuff(PChar(@CompTable[#0]), 256);
{$ENDIF}
end; end;
end; end;
@ -245,6 +252,7 @@ end;
procedure TSynEditSearch.SetSensitive(const Value: Boolean); procedure TSynEditSearch.SetSensitive(const Value: Boolean);
begin begin
if fSensitive <> Value then begin if fSensitive <> Value then begin
writeln('A');
fSensitive := Value; fSensitive := Value;
MakeCompTable(Value); MakeCompTable(Value);
fShiftInitialized := FALSE; 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; constructor Create(AOwner: TComponent); override;
end; end;
TLazSyntaxHighlighter =
(lshNone, lshText, lshFreePascal, lshDelphi, lshLFM, lshXML);
const
LazSyntaxHighlighterNames : array[TLazSyntaxHighlighter] of string = (
'None',
'Text',
'FreePascal',
'Delphi',
'LFM',
'XML'
);
var var
EditorOptionsForm: TEditorOptionsForm; EditorOptionsForm: TEditorOptionsForm;
EditorOpts: TEditorOptions; EditorOpts: TEditorOptions;
function ShowEditorOptionsDialog:TModalResult; function ShowEditorOptionsDialog:TModalResult;
function StrToLazSyntaxHighlighter(s: string): TLazSyntaxHighlighter;
function ExtensionToLazSyntaxHighlighter(Ext:string): TLazSyntaxHighlighter;
implementation implementation
@ -404,6 +421,44 @@ begin
end; end;
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 const
EditOptsConfFileName = 'editoroptions.xml'; EditOptsConfFileName = 'editoroptions.xml';
@ -663,9 +718,9 @@ begin
XMLConfig.SetValue('EditorOptions/Display/RightMargin',fRightMargin); XMLConfig.SetValue('EditorOptions/Display/RightMargin',fRightMargin);
XMLConfig.SetValue('EditorOptions/Display/RightMarginColor',fRightMarginColor); XMLConfig.SetValue('EditorOptions/Display/RightMarginColor',fRightMarginColor);
XMLConfig.SetValue('EditorOptions/Display/EditorFont',fEditorFont); XMLConfig.SetValue('EditorOptions/Display/EditorFont',fEditorFont);
XMLConfig.GetValue('EditorOptions/Display/EditorFontHeight' XMLConfig.SetValue('EditorOptions/Display/EditorFontHeight'
,fEditorFontHeight); ,fEditorFontHeight);
XMLConfig.GetValue('EditorOptions/Display/ExtraLineSpacing' XMLConfig.SetValue('EditorOptions/Display/ExtraLineSpacing'
,fExtraLineSpacing); ,fExtraLineSpacing);
// Key Mappings options // Key Mappings options

View File

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