TTextStrings improvements (Exchange, Put), clean ups

git-svn-id: trunk@6293 -
This commit is contained in:
mattias 2004-11-24 08:18:13 +00:00
parent 784cf31d12
commit ff0abfca3e
4 changed files with 406 additions and 205 deletions

View File

@ -1753,7 +1753,7 @@ end;
procedure TDebugManager.ProcessCommand(Command: word; var Handled: boolean);
begin
debugln('TDebugManager.ProcessCommand ',dbgs(Command));
//debugln('TDebugManager.ProcessCommand ',dbgs(Command));
Handled:=true;
case Command of
ecPause: DoPauseProject;
@ -1941,6 +1941,9 @@ end.
{ =============================================================================
$Log$
Revision 1.79 2004/11/24 08:18:13 mattias
TTextStrings improvements (Exchange, Put), clean ups
Revision 1.78 2004/11/23 11:01:10 mattias
added key handling for debug manager

View File

@ -238,6 +238,7 @@ type
procedure mnuConfigBuildFileClicked(Sender: TObject);
// components menu
// see pkgmanager.pas
// tools menu
procedure mnuToolConfigureClicked(Sender: TObject);
@ -264,7 +265,7 @@ type
// windows menu
// help menu
// see HelpManager.pas
// see helpmanager.pas
procedure OpenFileDownArrowClicked(Sender: TObject);
procedure mnuOpenFilePopupClick(Sender: TObject);
@ -323,7 +324,8 @@ type
procedure OnPropHookGetMethods(TypeData:PTypeData; Proc:TGetStringProc);
function OnPropHookMethodExists(const AMethodName:ShortString;
TypeData: PTypeData;
var MethodIsCompatible,MethodIsPublished,IdentIsMethod: boolean):boolean;
var MethodIsCompatible, MethodIsPublished,
IdentIsMethod: boolean): boolean;
function OnPropHookCreateMethod(const AMethodName:ShortString;
ATypeInfo:PTypeInfo): TMethod;
procedure OnPropHookShowMethod(const AMethodName:ShortString);
@ -5353,6 +5355,7 @@ Begin
ProjectDesc.CreateStartFiles(Project1);
// rebuild codetools defines
RescanCompilerDefines(true);
// (i.e. remove old project specific things and create new)
IncreaseCompilerParseStamp;
Project1.DefineTemplates.AllChanged;
@ -10962,6 +10965,9 @@ end.
{ =============================================================================
$Log$
Revision 1.798 2004/11/24 08:18:13 mattias
TTextStrings improvements (Exchange, Put), clean ups
Revision 1.797 2004/11/23 11:01:10 mattias
added key handling for debug manager

View File

@ -44,7 +44,7 @@ type
function GetCount: integer; virtual; abstract;
function GetItems(Index: integer): TNewIDEItemTemplate; virtual; abstract;
public
constructor Create(const AName: string); virtual; {$IFNDEF VER1_0}abstract;{$ENDIF}
constructor Create(const AName: string); virtual;
procedure Clear; virtual; abstract;
procedure Add(ATemplate: TNewIDEItemTemplate); virtual; abstract;
function LocalizedName: string; virtual; abstract;
@ -131,16 +131,13 @@ begin
NewIDEItems.UnregisterItem(NewItem);
end;
{ TNewIDEItemCategory }
{$IFDEF VER1_0}
constructor TNewIDEItemCategory.Create(const AName: string);
//fpc 1.0 doesn't support virtual abstract constructors,
//so we just make it virtual
{ TNewIDEItemCategory }
constructor TNewIDEItemCategory.Create(const AName: string);
begin
end;
{$ENDIF}
{ TNewIDEItemTemplate }

View File

@ -26,13 +26,9 @@
UNDER CONSTRUCTION by Mattias Gaertner
ToDo:
- Exchange
- Put
- Sort
- CustomSort
- Find
- Index
- Add
- Move
- IndexOf
}
unit TextStrings;
@ -50,7 +46,7 @@ type
StartPos: integer; // start of line in Text
EndPos: integer; // end of line in Text (= start of newline character(s))
Line: string; // cached line as string
TheObject: TObject;
TheObject: TObject; // user data
end;
TTextStrings = class(TStrings)
@ -64,6 +60,7 @@ type
FLineRanges: ^TTextLineRange;// array of TTextLineRange
FText: string;
FUpdateCount: integer;
FChangedWhileUpdate: boolean;
function GetTextStr: string; override;
procedure SetTextStr(const AValue: string); override;
procedure BuildArrays; virtual;
@ -73,6 +70,7 @@ type
function Get(Index: Integer): string; override;
procedure ClearArrays;
function GetObject(Index: Integer): TObject; override;
procedure Put(Index: Integer; const S: string); override;
procedure PutObject(Index: Integer; AnObject: TObject); override;
function GetLineLen(Index: integer; IncludeNewLineChars: boolean): integer;
public
@ -82,7 +80,14 @@ type
procedure Insert(Index: Integer; const S: string); override;
procedure Delete(Index: Integer); override;
procedure Exchange(Index1, Index2: Integer); override;
procedure Move(CurIndex, NewIndex: Integer); override;
procedure MakeTextBufferUnique;
procedure BeginUpdate;
procedure EndUpdate;
function GetText: PChar; override;
function IndexOf(const S: string): Integer; override;
function Add(const S: string): Integer; override;
procedure AddStrings(TheStrings: TStrings); override;
public
property Text: string read FText write SetTextStr;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
@ -167,8 +172,12 @@ begin
end;
procedure TTextStrings.Changed;
// called after text changed
begin
if (FUpdateCount=0) then
if (FUpdateCount>0) then begin
FChangedWhileUpdate:=true;
exit;
end;
if Assigned(FOnChange) then
FOnChange(Self);
end;
@ -215,6 +224,48 @@ begin
Result:=nil;
end;
procedure TTextStrings.Put(Index: Integer; const S: string);
var
OldLineLen: Integer;
NewLineLen: Integer;
Movement: Integer;
OldStartPos: LongInt;
OldEndPos: LongInt;
MoveLen: Integer;
i: Integer;
NewEndPos: Integer;
begin
if not FArraysValid then BuildArrays;
OldStartPos:=FLineRanges[Index].StartPos;
OldEndPos:=FLineRanges[Index].EndPos;
NewLineLen:=length(s);
OldLineLen:=OldEndPos-OldStartPos;
Movement:=NewLineLen-OldLineLen;
NewEndPos:=OldEndPos+Movement;
// move text behind
MoveLen:=length(FText)-OldEndPos;
if (Movement<>0) and (MoveLen>0) then begin
SetLength(FText,length(FText)+Movement);
System.Move(FText[OldEndPos],FText[NewEndPos],MoveLen);
for i:=Index+1 to FLineCount-1 do begin
inc(FLineRanges[i].StartPos,Movement);
inc(FLineRanges[i].EndPos,Movement);
end;
end;
FLineRanges[Index].EndPos:=NewEndPos;
// copy text
if NewLineLen>0 then
System.Move(S[1],FText[OldStartPos],NewLineLen);
FLineRanges[Index].Line:=S;
// check if arrays need rebuild
i:=NewLineLen;
while (i>0) and (not (S[i] in [#10,#13])) do dec(i);
if i>0 then begin
// S contains new line chars => rebuild needed
FArraysValid:=false;
end;
end;
procedure TTextStrings.PutObject(Index: Integer; AnObject: TObject);
begin
if not FArraysValid then BuildArrays;
@ -262,23 +313,29 @@ var
NewLineCharCount: Integer;
NewLineLen: Integer;
i: Integer;
SEndsInNewLine: boolean;
begin
if not FArraysValid then BuildArrays;
NewLineLen:=length(S);
SEndsInNewLine:=(S<>'') and (S[NewLineLen] in [#10,#13]);
if Index<FLineCount then
NewStartPos:=FLineRanges[Index].StartPos
else
NewStartPos:=length(FText);
NewLineCharCount:=0;
if (NewLineLen>0) and (S[NewLineLen] in [#10,#13]) then begin
if SEndsInNewLine then begin
inc(NewLineCharCount);
if (NewLineLen>1)
and (S[NewLineLen-1] in [#10,#13])
and (S[NewLineLen-1]<>S[NewLineLen]) then
inc(NewLineCharCount);
end;
// adjust text
System.Insert(S,FText,NewStartPos);
end else begin
// append missing newline char
System.Insert(S+LineEnding,FText,NewStartPos);
NewLineCharCount:=length(LineEnding);
inc(NewLineLen,NewLineCharCount);
end;
// adjust arrays
if FLineCount=FLineCapacity then begin
if FLineCapacity<8 then
@ -327,19 +384,113 @@ begin
end;
procedure TTextStrings.Exchange(Index1, Index2: Integer);
procedure RaiseIndex1Neg;
begin
raise Exception.Create('TTextStrings.Exchange Index1<=0');
end;
procedure RaiseIndex2Neg;
begin
raise Exception.Create('TTextStrings.Exchange Index2<=0');
end;
procedure RaiseIndex1Big;
begin
raise Exception.Create('TTextStrings.Exchange Index1>=FLineCount');
end;
procedure RaiseIndex2Big;
begin
raise Exception.Create('TTextStrings.Exchange Index2>=FLineCount');
end;
var
LineLen1: Integer;
LineLen2: Integer;
buf: Pointer;
Dummy: Integer;
OldBetweenStart: Integer;
NewBetweenStart: Integer;
BetweenLength: Integer;
StartPos1: LongInt;
StartPos2: LongInt;
DummyRange: TTextLineRange;
i: Integer;
Movement: Integer;
begin
// check values
if Index1=Index2 then exit;
if Index1<=0 then RaiseIndex1Neg;
if Index2<=0 then RaiseIndex2Neg;
if Index1>=FLineCount then RaiseIndex1Big;
if Index2>=FLineCount then RaiseIndex2Big;
// make sure Index1<Index2
if Index1>Index2 then begin
Dummy:=Index1;
Index1:=Index2;
Index2:=Dummy;
end;
// get line lengths including new line chars
if not FArraysValid then BuildArrays;
LineLen1:=GetLineLen(Index1,true);
LineLen2:=GetLineLen(Index2,true);
if (LineLen1<1) and (LineLen2<1) then exit;
// adjust text
MakeTextBufferUnique;
// save the bigger line
StartPos1:=FLineRanges[Index1].StartPos;
StartPos2:=FLineRanges[Index2].StartPos;
if LineLen1>=LineLen2 then begin
GetMem(buf,LineLen1);
System.Move(FText[StartPos1],buf^,LineLen1);
end else begin
GetMem(buf,LineLen2);
System.Move(FText[StartPos2],buf^,LineLen2);
end;
// move text in between
OldBetweenStart:=StartPos1+LineLen1;
BetweenLength:=StartPos2-OldBetweenStart;
NewBetweenStart:=StartPos1+LineLen2;
if (BetweenLength>0) and (OldBetweenStart<>NewBetweenStart) then
System.Move(FText[OldBetweenStart],FText[NewBetweenStart],BetweenLength);
// move both lines
if LineLen1>=LineLen2 then begin
System.Move(FText[StartPos2],FText[StartPos1],LineLen2);
System.Move(buf^,FText[StartPos2],LineLen1);
end else begin
System.Move(FText[StartPos1],FText[StartPos2],LineLen1);
System.Move(buf^,FText[StartPos1],LineLen2);
end;
// adjust line ranges
if LineLen1<>LineLen2 then begin
System.Move(FLineRanges[Index1],DummyRange,SizeOf(TTextLineRange));
System.Move(FLineRanges[Index2],FLineRanges[Index1],SizeOf(TTextLineRange));
System.Move(DummyRange,FLineRanges[Index2],SizeOf(TTextLineRange));
if (BetweenLength>0) and (OldBetweenStart<>NewBetweenStart) then begin
Movement:=NewBetweenStart-OldBetweenStart;
for i:=Index1+1 to Index2-1 do begin
inc(FLineRanges[i].StartPos,Movement);
inc(FLineRanges[i].EndPos,Movement);
end;
end;
end;
// clean up
FreeMem(buf);
end;
procedure TTextStrings.Move(CurIndex, NewIndex: Integer);
begin
// TODO
inherited Move(CurIndex, NewIndex);
end;
procedure TTextStrings.MakeTextBufferUnique;
@ -348,5 +499,49 @@ begin
UniqueString(FText);
end;
procedure TTextStrings.BeginUpdate;
begin
inc(FUpdateCount);
end;
procedure TTextStrings.EndUpdate;
begin
if FUpdateCount<=0 then
raise Exception.Create('TTextStrings.EndUpdate');
dec(FUpdateCount);
if FUpdateCount=0 then begin
if FChangedWhileUpdate then
Changed;
end;
end;
function TTextStrings.GetText: PChar;
begin
Result:=PChar(FText);
end;
function TTextStrings.IndexOf(const S: string): Integer;
begin
// TODO
Result:=inherited IndexOf(S);
end;
function TTextStrings.Add(const S: string): Integer;
begin
// TODO
Result:=inherited Add(S);
end;
procedure TTextStrings.AddStrings(TheStrings: TStrings);
var
s: String;
begin
if (FText<>'') and (not (FText[length(FText)] in [#10,#13])) then
s:=LineEnding
else
s:='';
Text:=Text+s+TheStrings.Text;
end;
end.