//---------------------------------------------------------- // //---------------------------------------------------------- unit Editor; interface uses //---------------------------------------------------------- //local //----------------------------------------------------------
GenDefs,Language,CodeCompletion,Undo, //---------------------------------------------------------- //global //----------------------------------------------------------
SysUtils,Classes,Controls,StdCtrls,ComCtrls,Messages,
Graphics,Types,ShellAPI,RichEdit; //---------------------------------------------------------- // //---------------------------------------------------------- const
maxinputbuffer=100000;
leastmargin=5;
CH_Blank=' ';
CH_Return=chr(Key_Return);
CH_LineFeed=chr(Key_LineFeed);
CH_Tab=chr(Key_Tab);
unallowedchars:setof ansichar=[CH_Blank,CH_Return,CH_LineFeed,CH_Tab];
{$I ownconsts.inc} //---------------------------------------------------------------------------- //rtf formats //----------------------------------------------------------------------------
RtfParagraph='\par';
SetSize='\f1\fs';
SetColor='\cf';
SetNoColor='\cf0';
Underline='\ul ';
UnderLineOff='\ulnone';
Bold='\b';
BoldOff='\b0 ';
Subscript='\sub ';
SubscriptOff='\nosupersub ';
Superscript='\super ';
SuperscriptOff='\nosupersub ';
Strike='\strike';
StrikeOff='\strike0';
Italic='\i';
ItalicOff='\i0';
Font0='\i\f0 ';
Font1='\i\f1 ';
Font2='\i\f2 ';
Font3='\i\f3';
SetBackColor='\f1\cb1\cf';
SetNoBackColor='';//funktioniert nicht
Omega='\u963?';//Achtung: Zahl (963) ist dezimal Landau-Symbol
Summenzeichen='\u931?';//dito
Produktzeichen='\u928?';//dito //---------------------------------------------------------- // //---------------------------------------------------------- type
{$I owntypes.inc} //---------------------------------------------------------------------------- //Longtexts of Trees //----------------------------------------------------------------------------
TSingleAttribute= record
yyfil:JString40;
yylin:integer;
yycol:integer;
yylen:integer;
yycolor:JString8;
yyindent:integer; end;
TAttrList= record
Y: arrayof TSingleAttribute;
AttrCount:integer; end;
LineMemory= record
lines: arrayofinteger;
count:integerend; //---------------------------------------------------------- // //----------------------------------------------------------
TEde= Class(TRichEdit)private //
protected procedure CreateWnd;
override;
published constructor Create(AOwner:TComponent);override; destructor Destroy;override; function printablechar(ch:char):boolean; procedure SaveToUndoBuffer(); procedure LoadFromUndoBuffer(); procedure InitUndoBuffer(); function SetRtfAttributes(Efs:JString;streamin:TStream; var streamout:TStream):boolean; function CreateHighlited(Nr:integer):TimeTripel; procedure Mark(); procedure CreatePlain(Nr:integer); procedure CreateString(Stdout,Stderr:JString); procedure CreateBin(Nr:integer); procedure SaveRtfTo(S:JString); procedure initLinearray(Anz:integer); procedure markLinePos(L,C:integer); procedure markWord(L,C,LL:integer); procedure setCharPos(P,L:integer); function getFirstVisibleLine():integer; function getLastVisibleLine():integer; function getLineHeight():integer; function getRectBottom():integer; function getFileNumber(TFile:JString):integer; function getNumberofVisibleLines():integer; function getLinefromCharIndex(C:integer):integer; function getCharIndexfromLine(L:integer):integer; function GetTextRange(BeginPos,EndPos:integer):JString; function getDotFromChar(C:integer):TPoint; procedure getCurrentWord(); function getWordBounds(P:integer):TPoint; function getPos():TPoint; function Occurrence(S:JString):integer; procedure CreateDummyFile(); procedure errorn(n:integer;S:JString); function ask(n:integer;S,Z:JString):integer; function inform(n:integer;S,Z:JString):boolean; function Save(askhim:boolean):integer; procedure makeLineBlockNumbers(); procedure searchreplace(Kind:SeaRepFun); procedure WindProc(var Message:TMessage); procedure OnMouse(var Message:TMessage); procedure OnMouseDbl(var Message:TMessage); procedure OnKey(var Message:TMessage); procedure Indenting(var Message:TMessage); procedure Bracketing(); procedure PositEditor; procedure PositioningCorrect(from,num:integer); procedure Scroller(WheelDelta:integer); function RtfHeader():AnsiString; procedure LoadAttributes(TC:PAnsiChar); procedure LoadHighLites(Hi: arrayof TColor); procedure LoadNames(Ar: arrayofString); function getVScrollPos():integer; function getScrollPos():TPoint; procedure setScrollPos(P:TPoint); function getPosMod(R:TPoint):TPoint; procedure setl(var a: arrayofchar;S:JString); procedure Representation(var S:JString;var streamout:TStream); function getCharat(pos:integer):char; procedure ShowRedraw(); procedure HideRedraw(); procedure CreateRtfReadOnly(Nr:integer); function findsingle(Start:integer):TRegInfo; function findregular(Rex:TRegExp;Start:integer):TRegInfo; function findset(Start:integer;se:ansiset):TRegInfo; function findmeta(Start:integer;ch:ansichar):TRegInfo; procedure setSearchString(Str:JString;regex:boolean); procedure parse(Str:JString); procedure addmeta(var Reg:TRegExp;ch:char); procedure addset(var Reg:TRegExp;Str:JString); procedure ScrollLeft(); procedure InsertStream(const Stream:TStream); procedure clearUndoBuffer(); procedure settabs(); procedure flushstreams(); procedure clearstreams();
published procedure CNNotify(var Msg:TMessage); public //technical fields
linemargin:integer;
KeyFound:boolean;
CreateBackup:boolean;
hasRepresentation:boolean;
SearchString,ReplaceString:TextString;
MinCol,NumCol,MaxCol:integer;
MaxColFound,MaxLineCount:integer;
FoundAt,RegularStartPos:integer;
Wrapped:boolean;
brack1,brack2:integer;
LoadedFile:String;
LoadedFileNumber:integer;
LoadedFormat:SourceTypes;
InputFormat:SourceFormats;
TA:TAttrList;
Syntaxbold,SyntaxHighlight,ShowSpaces:boolean;
Blocknumbers,LineNumbers:boolean;
Highlites: array [Highlite] of TColor;
oldwinproc:TWndMethod;
Uli,Ulibuf:TUndoList;
Regexp:TRegExp;
Regexplength:integer;
Parsecheck:boolean;
CodeCompleter:TCodeWindow;
Sources: arrayofString;
Buffer:JString;
Buffillled,Super,Sub:boolean;
CurrentWord:JString;
lang:Naturallanguages;
casesensitive:boolean;
dowordwrap:boolean;
regexpsearch:boolean;
indentingpossible:boolean;
doindent:boolean;
indentchars:integer;
Artificiallines:boolean;
reloading:boolean;
showURL:boolean;
Linearray:LineMemory;
Blockarray:LineMemory;
streamatt:TStream;
streamfile:TFileStream;
streamorig:TFileStream; end; //---------------------------------------------------------- // //---------------------------------------------------------- procedure Register; implementation uses
Windows,Variants,Forms,Dialogs,jpeg,ExtCtrls,Menus,ToolWin,
Buttons,Math,StrUtils,ImgList,Printers,CheckLst,Clipbrd,
DateUtils,Tabs; //---------------------------------------------------------- // //---------------------------------------------------------- procedure Register; begin
RegisterComponents('cococo.de',[TEde]); end; //---------------------------------------------------------- // //---------------------------------------------------------- constructor TEde.Create(AOwner:TComponent); begin inherited Create(AOwner);
LoadedFile:='';
LoadedFormat:=RTF;
MinCol:=1;//do not shift
NumCol:=6;//do not shift
MaxCol:=72;
brack1:=0;
brack2:=0;
clearUndoBuffer();
Regexp:=nil;
Paragraph.FirstIndent:=margin;
CodeCompleter:=TCodeWindow.Create(self);
hasRepresentation:=false;
casesensitive:=false;
regexpsearch:=false;
reloading:=false;
showURL:=true;
doindent:=false;
streamatt:=nil;
streamfile:=nil;
indentchars:=1;
Artificiallines:=false;
indentingpossible:=false end; //---------------------------------------------------------- // //---------------------------------------------------------- destructor TEde.Destroy; begin if CodeCompleter.Visible then
CodeCompleter.setInvisible;
WindowProc:=oldwinproc;
CodeCompleter.Free;
Uli.Free; inherited; end; //---------------------------------------------------------- //set tab stops //---------------------------------------------------------- procedure TEde.settabs(); var
i,DialogUnitsX,PixelsX,sels,sell:integer;
modi:boolean; begin
modi:=Modified;
DialogUnitsX:=LoWord(GetDialogBaseUnits);
PixelsX:=25;
WantTabs:=true;
TabStop:=true;
Paragraph.TabCount:=10; for i:=1 to Paragraph.TabCount do
Paragraph.Tab[i-1]:=((PixelsX*i)*4)div DialogUnitsX;
sels:=SelStart;
sell:=SelLength;
selectall();
SelStart:=sels;
SelLength:=Sell;
Modified:=modi; end; //---------------------------------------------------------- //experimental: insert stream into rtf //---------------------------------------------------------- procedure TEde.InsertStream(const Stream:TStream); var
EditStream:TEditStream;//callback used to read inserted RTF //call back function function EditStreamReader(dwCookie:DWORD;pBuff:Pointer;cb:LongInt;
pcb:PLongInt):DWORD;stdcall; begin
Result:=$0000;//assume no error try
pcb^:=TStream(dwCookie).Read(pBuff^,cb);//read data from stream except
Result:=$FFFF;//indicates error to calling routine end; end; begin
lines.BeginUpdate; try //Make sure rich edit is large enough to take inserted code
MaxLength:=MaxLength+Stream.Size; //Stream in the RTF via EM_STREAMIN message
EditStream.dwCookie:=DWORD(Stream);
EditStream.dwError:=$0000;
EditStream.pfnCallback:=@EditStreamReader;
Perform(EM_STREAMIN,SFF_SELECTION or SF_RTF or SFF_PLAINRTF,
LPARAM(@EditStream)); //Report any errors as a bug if EditStream.dwError<>$0000 then raise Exception.Create('RTFInsertStream: Error inserting stream'); finally
lines.EndUpdate; end; end; //---------------------------------------------------------- // //---------------------------------------------------------- function TEde.printablechar(ch:char):boolean; var
ok:boolean; begin
ok:=(ch>=' ')or(ord(ch)=9)or(ord(ch)=10)or(ord(ch)=13);
Result:=ok end; //---------------------------------------------------------- //bfi file size //---------------------------------------------------------- function getFileLength(F:JString;var binfile:boolean):integer; var
Strin:TFileStream;
CS:LongInt; begin
CS:=0;
binfile:=false; If FileExists(F) thenbegin
Strin:=TFileStream.Create(F,fmOpenRead or fmShareDenyNone);
CS:=Strin.Size;
binfile:=binfile or(pos('.exe',F)>0)or(pos('.dll',F)>0)or(pos('.com',F)>0)or
(pos('.ico',F)>0);
Strin.Free; end;
getFileLength:=CS; end; //------------------------------------------------------------------ //Procedure Setl //moving of short arrays //------------------------------------------------------------------ procedure TEde.setl(var a: arrayofchar;S:JString); var
i,sa,ls:integer; begin
sa:=sizeof(a);
ls:=length(S); for i:=0 to length(a)-1 do
a[i]:=chr(0);
i:=0; if ls>=sa then
errorn(101,'fataler Fehler') else while (i<ls)and(i<sa) dobegin
a[i]:=S[i+1];
i:=i+1 end; end; //---------------------------------------------------------- //Init //---------------------------------------------------------- procedure TEde.errorn(n:integer;S:JString); begin
showmessage(IntToStr(n)+': '+S); end; //---------------------------------------------------------- //Init //---------------------------------------------------------- function TEde.ask(n:integer;S,Z:JString):integer; var
MS:JString; begin
MS:=trans(lang,n,S)+Z;
Result:=MessageDlg(MS,mtInformation,[mbYes,mbNo,mbCancel],0); end; //---------------------------------------------------------- //Init //---------------------------------------------------------- function TEde.inform(n:integer;S,Z:JString):boolean; begin
S:=trans(lang,n,S)+Z;
Result:=MessageDlg(S,mtInformation,[mbOK],0)=mrOk; end; //---------------------------------------------------------- //Init //---------------------------------------------------------- procedure TEde.LoadNames(Ar: arrayofString); var
i,LL:integer; begin
LL:=length(Ar);
setlength(Sources,LL); for i:=0 topred(LL) do
Sources[i]:=Ar[i]; end; //------------------------------------------------------------------ //-- //get the files of a compilation/analysis -- //-- //------------------------------------------------------------------ function TEde.Occurrence(S:JString):integer; var
P,C,R:integer; begin
P:=0;
C:=0;
setSearchString(S,regexpsearch); repeat
R:=findsingle(P).pos; if R>0 thenbegin
C:=C+1;
P:=R+1; end; until R<0;
Occurrence:=C; end; //------------------------------------------------------------------ //-- //get the files of a compilation/analysis -- //-- //------------------------------------------------------------------ function TEde.getFileNumber(TFile:JString):integer; var
P:integer; begin
getFileNumber:=1; for P:=0 to length(Sources)-1 do if Sources[P]=TFile then
getFileNumber:=P; end; //------------------------------------------------------------------ //-- //------------------------------------------------------------------ function TEde.getScrollPos():TPoint; const
EM_getScrollPos=WM_User+221; var
P:TPoint; begin
SendMessage(Handle,EM_getScrollPos,0,LPARAM(@P));
getScrollPos:=P; end; //------------------------------------------------------------------ //-- //------------------------------------------------------------------ procedure TEde.setScrollPos(P:TPoint); const
EM_setScrollPos=WM_User+222; begin
SendMessage(Handle,EM_setScrollPos,0,LPARAM(@P)); end; //------------------------------------------------------------------ //-- //------------------------------------------------------------------ procedure TEde.ScrollLeft(); var
P:TPoint; begin
P:=getScrollPos();
P.X:=0;
setScrollPos(P); end; //------------------------------------------------------------------ //-- //------------------------------------------------------------------ function TEde.getVScrollPos():integer; const
EM_getScrollPos=WM_User+221; var
P:TPoint; begin
SendMessage(Handle,EM_getScrollPos,0,LPARAM(@P));
getVScrollPos:=P.Y; end; //------------------------------------------------------------------ // //------------------------------------------------------------------ procedure TEde.parse(Str:JString); var
P,ls:integer;
Reg:TRegExp;
ch:char;
sets:JString; begin
Reg:=nil;
P:=1;
ls:=length(Str); while (P<=ls)and(Str[P]<>']') dobegin
ch:=Str[P]; case ch of '^':
addmeta(Reg,ch); '.':
addmeta(Reg,ch); '$':
addmeta(Reg,ch); '[':begin
sets:=''; while (P<=ls)and(Str[P]<>']') dobegin
sets:=sets+Str[P];
P:=P+1; if (P<=ls)and(Str[P]='\') thenbegin
sets:=sets+Str[P];
P:=P+1;
sets:=sets+Str[P];
P:=P+1; end; end; if (P<=ls)and(Str[P]=']') then
sets:=sets+Str[P];
addset(Reg,sets); end else
Parsecheck:=false end;
P:=P+1 end;
Regexp:=Reg; end; //------------------------------------------------------------------ // //------------------------------------------------------------------ procedure TEde.setSearchString(Str:JString;regex:boolean); begin
regexpsearch:=regex;
setl(SearchString.S,Str);
SearchString.Regular:=regex; if regexpsearch then
parse(Str); end; //------------------------------------------------------------------ // //------------------------------------------------------------------ procedure TEde.addmeta(var Reg:TRegExp;ch:char); var
n:TRegExp; begin
n:=TRegExp.Create();
n.R:=single;
n.ch:=ansichar(ch); if Reg<>nilthen
Reg.append(n) else
Reg:=n; end; //------------------------------------------------------------------ // //------------------------------------------------------------------ procedure TEde.addset(var Reg:TRegExp;Str:JString); var
n:TRegExp;
last,prelast:char;
i,j,ls:integer; begin
n:=TRegExp.Create();
n.R:=Regset;
n.inset:=[];
i:=2;
last:=chr(0);
prelast:=chr(0);
ls:=length(Str); while (i<=ls)and(Str[i]<>']') dobegin if Str[i]='\'thenbegin
i:=i+1; if i>ls then
Parsecheck:=false end; if last='-'thenbegin for j:=ord(prelast)+1 toord(Str[i]) do
n.inset:=n.inset+[chr(j)] end elseif Str[i]<>'-'then
n.inset:=n.inset+[Str[i]];
prelast:=last;
last:=Str[i];
i:=i+1 end;
Parsecheck:=Parsecheck and(i<=ls)and(Str[i]=']'); if Reg<>nilthen
Reg.append(n) else
Reg:=n; end; //------------------------------------------------------------------ // //------------------------------------------------------------------ function TEde.findset(Start:integer;se:ansiset):TRegInfo; var
res:TRegInfo;
ch:ansichar;
Min,F,LL:integer;
Str:JString; begin
res.pos:=-1;
res.len:=1;
LL:=length(lines.Text); if (Start<LL)and(Start>=0) thenbegin
Min:=LL+1; for ch in se dobegin
Str:=ch; if casesensitive then
F:=FindText(Str,Start,LL,[stMatchCase]) else
F:=FindText(Str,Start,LL,[]); if F>=0 then if F<Min then
Min:=F; end; if Min<=LL then
res.pos:=Min; end;
Result:=res; end; //------------------------------------------------------------------ // //------------------------------------------------------------------ function TEde.findmeta(Start:integer;ch:ansichar):TRegInfo; var
res:TRegInfo;
Str:JString;
LL,ci:integer; begin
res.pos:=-1;
res.len:=1;
LL:=length(Text); if (Start<LL)and(Start>=0) thenbegin case ch of '^':begin
res.len:=0; if Start=0 then
res.pos:=0 elseif getLinefromCharIndex(Start)=lines.count then
res.pos:=-1 elseif GetTextRange(Start-1,Start-1)=chr(Key_Return) then
res.pos:=Start elsebegin
Str:=chr(Key_Return);
res.pos:=FindText(Str,Start,LL,[stMatchCase]); if res.pos>=0 thenbegin
ci:=getLinefromCharIndex(res.pos); if ci+1>=lines.count then
res.pos:=-1 else
res.pos:=res.pos+1; end; end; end; '$':begin
res.len:=1;
Str:=chr(Key_Return);
res.pos:=FindText(Str,Start,LL,[stMatchCase]);
ci:=getLinefromCharIndex(res.pos); if ci+1>=lines.count then
res.pos:=-1 end; '.':begin
res.ch:=getCharat(Start);
res.pos:=Start;
res.len:=1; end else
res.pos:=-1; end; end;
Result:=res; end; //------------------------------------------------------------------ //regular expression search //------------------------------------------------------------------ function TEde.findregular(Rex:TRegExp;Start:integer):TRegInfo; var
this,last,first:TRegInfo;
R:TRegExp;
pos,LL,overalllen,lenbefore,minpos:integer;
allfound,collating:boolean; function findone():TRegInfo; var
res:TRegInfo; begin if R.R=single then
res:=findmeta(pos,R.ch) else
res:=findset(pos,R.inset);
minpos:=max(minpos,res.pos-lenbefore);
pos:=pos+1;
lenbefore:=lenbefore+res.len;
R:=R.next;
Result:=res end; begin
pos:=Start;
LL:=length(lines.Text);
allfound:=true;
minpos:=pos; repeat
collating:=true;
lenbefore:=0;
R:=Rex;
first:=findone();
last:=first; while (R<>nil)and allfound and collating and(pos<LL)and(last.pos>=0) do begin
pos:=last.pos+last.len;
this:=findone();
allfound:=allfound and(this.pos>=0);
collating:=last.pos+last.len=this.pos;
last:=this; end;
overalllen:=lenbefore;
pos:=max(minpos-1,first.pos+1); until (collating and allfound)or(pos>=LL)ornot allfound; if collating and allfound thenbegin
first.len:=overalllen;
Result:=first; end elsebegin
first.pos:=-1;
first.len:=0;
Result:=first end end; //------------------------------------------------------------------ // //------------------------------------------------------------------ function TEde.findsingle(Start:integer):TRegInfo; var
res:TRegInfo; begin ifnot regexpsearch thenbegin
res.len:=length(String(SearchString.S)); if casesensitive then
res.pos:=FindText(SearchString.S,Start,length(lines.Text),[stMatchCase]) else
res.pos:=FindText(SearchString.S,Start,length(lines.Text),[]); end else
res:=findregular(Regexp,Start);
Result:=res; end; //------------------------------------------------------------------ //current word including '.' //------------------------------------------------------------------ procedure TEde.getCurrentWord(); var
LeftPos,OrigStart,RightPos:integer; begin
LeftPos:=SelStart;
OrigStart:=SelStart; //go to the left
LeftPos:=SendMessage(Handle,EM_FINDWORDBREAK,WB_MOVEWORDLEFT,LeftPos);
CurrentWord:=GetTextRange(LeftPos,OrigStart); if CurrentWord>''thenbegin while CurrentWord[1]='.'dobegin
LeftPos:=SendMessage(Handle,EM_FINDWORDBREAK,WB_MOVEWORDLEFT,LeftPos);
CurrentWord:=GetTextRange(LeftPos,OrigStart); end; end; if LeftPos<=0 then
LeftPos:=OrigStart; //go to the right
RightPos:=SendMessage(Handle,EM_FINDWORDBREAK,WB_MOVEWORDRIGHT,OrigStart+1); if RightPos>-1 then
CurrentWord:=GetTextRange(LeftPos,RightPos-1); if CurrentWord>''thenbegin while CurrentWord[length(CurrentWord)]='.'dobegin
RightPos:=SendMessage(Handle,EM_FINDWORDBREAK,WB_MOVEWORDLEFT,RightPos);
CurrentWord:=GetTextRange(LeftPos,RightPos); end; end; end; //------------------------------------------------------------------ //current word including '.' //------------------------------------------------------------------ function TEde.getWordBounds(P:integer):TPoint; var
LeftPos,OrigStart,RightPos:integer;
R:TPoint; begin
LeftPos:=P;
OrigStart:=P;
R.X:=P;
R.Y:=P; //go to the left
LeftPos:=SendMessage(Handle,EM_FINDWORDBREAK,WB_MOVEWORDLEFT,LeftPos); if LeftPos<=0 then
LeftPos:=OrigStart;
R.X:=LeftPos; //go to the right
RightPos:=SendMessage(Handle,EM_FINDWORDBREAK,WB_MOVEWORDRIGHT,LeftPos);
R.Y:=RightPos;
Result:=R end; //------------------------------------------------------------------ //-- //------------------------------------------------------------------ function TEde.getFirstVisibleLine():integer; begin
getFirstVisibleLine:=Perform(EM_GETFIRSTVISIBLELINE,0,0)+1; end; //------------------------------------------------------------------ //-- //------------------------------------------------------------------ function TEde.getLinefromCharIndex(C:integer):integer; begin
getLinefromCharIndex:=Perform(EM_LINEFROMCHAR,C,0); end; //------------------------------------------------------------------ //-- //------------------------------------------------------------------ function TEde.getCharIndexfromLine(L:integer):integer; begin
getCharIndexfromLine:=Perform(EM_LINEINDEX,L,0) end; //------------------------------------------------------------------ //-- //------------------------------------------------------------------ function TEde.getNumberofVisibleLines():integer; var
hdc:THandle;
EditRect:TRect;
RectHeight:integer;
tm:TextMetric; begin
hdc:=GetDC(Handle);
Perform(EM_GETRECT,0,EditRect);
RectHeight:=EditRect.bottom-EditRect.top;
GetTextMetrics(hdc,tm);
getNumberofVisibleLines:=(RectHeight div font.Size)+1; end; //------------------------------------------------------------------ //-- //------------------------------------------------------------------ function TEde.getLastVisibleLine():integer; var
EditRect:TRect;
RectHeight,MaxNumberofLines:integer;
FirstVisibleLine:integer; begin
Perform(EM_GETRECT,0,EditRect);
RectHeight:=EditRect.bottom-EditRect.top;
MaxNumberofLines:=(RectHeight div font.Size)+1;
FirstVisibleLine:=getFirstVisibleLine();
getLastVisibleLine:=FirstVisibleLine+MaxNumberofLines end; //------------------------------------------------------------------ //-- //------------------------------------------------------------------ function TEde.getLineHeight():integer; var
EditRect:TRect;
RectHeight:integer; begin
Perform(EM_GETRECT,0,EditRect);
RectHeight:=EditRect.bottom-EditRect.top;
getLineHeight:=(RectHeight div font.Size)+1; end; //------------------------------------------------------------------ //-- //------------------------------------------------------------------ function TEde.getDotFromChar(C:integer):TPoint; var
P:TPoint; begin
Perform(EM_POSFROMCHAR,Wparam(@P),C);
getDotFromChar:=P end; //------------------------------------------------------------------ //-- //------------------------------------------------------------------ function TEde.getPos():TPoint; begin
Result.X:=CaretPos.X+1;
Result.Y:=CaretPos.Y+1 end; //------------------------------------------------------------------ //-- //------------------------------------------------------------------ function TEde.getRectBottom():integer; var
EditRect:TRect; begin
Perform(EM_GETRECT,0,EditRect);
getRectBottom:=EditRect.bottom; end; //------------------------------------------------------------------ //-- //------------------------------------------------------------------ function TEde.getPosMod(R:TPoint):TPoint; var
L,i,LL:integer;
E:TPoint; begin
E.X:=R.X;
E.Y:=R.Y;
L:=R.Y;
LL:=Linearray.count; if LL>=L then if Linearray.lines[L]<>L thenbegin
i:=0; while i<LL-1 dobegin if Linearray.lines[i]=L thenbegin
L:=i;
i:=LL end;
i:=i+1 end;
R.Y:=L; end else
R.Y:=L;
getPosMod:=E end; //------------------------------------------------------------------ //-- //------------------------------------------------------------------ procedure TEde.markLinePos(L,C:integer); var
FirstVisible,Diff,Inx,in1,LL,lb:integer;
Buf: record Siz:Word;
cont: array [0..100] ofchar; end;
P :
TPoint; begin
FirstVisible:=getFirstVisibleLine();
LL:=Linearray.count; if L<LL thenbegin
L:=Linearray.lines[L];
Diff:=L-FirstVisible;
Perform(EM_LINESCROLL,C,Diff); //show selected
Perform(EM_HIDESELECTION,0,0); //fetch index
Inx:=getCharIndexfromLine(L-1)+C-1; //inspect line
Buf.Siz:=length(Buf.cont);
Perform(EM_GETLINE,L-1,@Buf);
in1:=C;
lb:=length(Buf.cont); while (in1<lb)and(Buf.cont[in1]<>' ')and(Buf.cont[in1]>'') do
in1:=in1+1; //now posit
Perform(EM_SETSEL,Inx,Inx+in1-C+1);
P:=getWordBounds(Inx+in1-C); if P.Y>P.X then
Perform(EM_SETSEL,P.X,P.Y); end; end; //------------------------------------------------------------------ //-- //------------------------------------------------------------------ procedure TEde.markWord(L,C,LL:integer); var
FirstVisible,Diff,Inx:integer; begin
FirstVisible:=getFirstVisibleLine(); if L<Linearray.count thenbegin
L:=Linearray.lines[L];
Diff:=L-FirstVisible;
Perform(EM_LINESCROLL,C,Diff); //show selected
Perform(EM_HIDESELECTION,0,0); //fetch index
Inx:=getCharIndexfromLine(L-1); //now posit
Perform(EM_SETSEL,Inx+C-1,Inx+C-1+LL); end; end; //------------------------------------------------------------------ //-- //------------------------------------------------------------------ procedure TEde.setCharPos(P,L:integer); var
FirstVisible,Target,Diff:integer; begin
FirstVisible:=getFirstVisibleLine();
Target:=Perform(EM_LINEFROMCHAR,P,0);
Diff:=Target-FirstVisible;
Perform(EM_LINESCROLL,L,Diff);
SelStart:=P;
SelLength:=L; end; //---------------------------------------------------------- //save //---------------------------------------------------------- procedure TEde.SaveToUndoBuffer(); var
i,LL:integer; begin if Uli=nilthen
Uli:=TUndoList.Create(MaxLength,SelStart,SelLength) elsebegin
Uli.next:=TUndoList.Create(MaxLength,SelStart,SelLength);
Uli.next.Previous:=Uli;
Uli:=Uli.next; end; //Reset buffer and save data
Uli.UndoBuffer.SetSize(0);
Uli.UndoBuffer.Position:=0;
lines.SaveToStream(Uli.UndoBuffer); //save also Line- and Blockarray
LL:=Linearray.count;
setlength(Uli.Linearray,LL); for i:=0 to LL-1 do
Uli.Linearray[i]:=Linearray.lines[i];
setlength(Uli.Blockarray,LL); for i:=0 to LL-1 do
Uli.Blockarray[i]:=Blockarray.lines[i]; //Store graphical information (cursor position etc.)
Uli.FirstVisibleLine:=getFirstVisibleLine();
Uli.UndoSelStart:=SelStart;
Uli.UndoSelLength:=SelLength;
Uli.UndoModified:=Modified; end; //---------------------------------------------------------- //save //---------------------------------------------------------- procedure TEde.InitUndoBuffer(); begin
clearUndoBuffer();
SaveToUndoBuffer(); end; //---------------------------------------------------------- //save //---------------------------------------------------------- procedure TEde.clearUndoBuffer(); begin
Uli:=nil; end; //---------------------------------------------------------- //load //---------------------------------------------------------- procedure TEde.LoadFromUndoBuffer(); var
indentnow,i,LL,sels,sell:integer; begin //cu:=Perform(EM_CANUNDO,0,0); //if Modified and(cu<>0) then begin //Perform(EM_UNDO,0,0); //Refresh(); //end; if Uli<>nilthenbegin
indentnow:=Paragraph.leftIndent;
lines.BeginUpdate;
Uli.UndoBuffer.Position:=0;
lines.LoadFromStream(Uli.UndoBuffer); //save also Line- and Blockarray
LL:=length(Uli.Linearray);
setlength(Linearray.lines,LL); for i:=0 to LL-1 do
Linearray.lines[i]:=Uli.Linearray[i];
setlength(Blockarray.lines,LL); for i:=0 to LL-1 do
Blockarray.lines[i]:=Uli.Blockarray[i]; //repair indent
sels:=SelStart;
sell:=SelLength;
selectall();
SelStart:=sels;
SelLength:=Sell;
Paragraph.Alignment:=taLeftJustify;
Paragraph.leftIndent:=indentnow;
Paragraph.FirstIndent:=indentnow;
SelLength:=0;
markLinePos(Uli.FirstVisibleLine,0);
lines.EndUpdate;
Refresh();
SelStart:=Uli.UndoSelStart;
SelLength:=Uli.UndoSelLength;
Modified:=Uli.UndoModified; if Uli.Previous<>nilthenbegin
Uli.UndoBuffer.Free;
Uli.UndoBuffer:=nil;
Uli:=Uli.Previous; end else
Modified:=false;
Uli.next:=nil; end; end; //----------------------------------------------------------------- //external Representation //Isabelle special characters //------------------------------------------------------------------ procedure TEde.Representation(var S:JString;var streamout:TStream); var
suboff:boolean;
i,j,k,hex:integer;
CC,DD:JString; begin
suboff:=Super or Sub; if (S='\\') then //prettyprint is uncomplete!!!
Buffillled:=true; if Buffillled thenbegin if (Buffer='\\')and(S<>'<') thenbegin //ignore
S:=Buffer+Buffer+' '+S;
Buffillled:=false;
Buffer:=''; for i:=2 to length(S) do
streamout.WriteBuffer(S[i],1); end elseif (S<>'>')and(S<>'\') then
Buffer:=Buffer+S //add to buffer elsebegin//empty buffer
CC:=midstr(Buffer,4,length(Buffer)-1); if (CC='^isup')or(CC='^sup') thenbegin
S:='\up'+IntToStr(font.Size div 2)+' ';
Buffillled:=false;
Buffer:=''; for i:=1 to length(S) do
streamout.WriteBuffer(S[i],1);
Super:=true; end elseif (CC='^isub')or(CC='^sub') thenbegin
S:='\dn'+IntToStr(font.Size div 2)+' ';
Buffillled:=false;
Buffer:=''; for i:=1 to length(S) do
streamout.WriteBuffer(S[i],1);
Sub:=true; end else for j:=1 to length(Isabelle) dobegin
k:=10; while (k<length(Isabelle[j]))and(Isabelle[j][k]<>'>') do
k:=k+1;
DD:=midstr(Isabelle[j],10,k-10); if CC=DD thenbegin
hex:=0;
S:=midstr(Isabelle[j],38,8);
TryStrtoInt(S,hex);
S:=Font2+'\u'+IntToStr(hex)+'?'+Font0;
Buffillled:=false;
Buffer:=''; for i:=1 to length(S) do
streamout.WriteBuffer(S[i],1); end; end; if Buffillled thenbegin
S:=Buffer+S;
Buffillled:=false;
Buffer:=''; for i:=1 to length(S) do
streamout.WriteBuffer(S[i],1); end; end; end else for i:=1 to length(S) do
streamout.WriteBuffer(S[i],1); if suboff andnot Buffillled thenbegin
Super:=false;
Sub:=false; if Sub then
S:='\dn0 ' else
S:='\up0 '; for i:=1 to length(S) do
streamout.WriteBuffer(S[i],1); end; end; //------------------------------------------------------------------ //-- //set Attributes -- //-- //------------------------------------------------------------------ function TEde.SetRtfAttributes(Efs:JString;streamin:TStream; var streamout:TStream):boolean; var
Line,RealColumn,NextColumn,Att,ccol,klauf,klzu,lastgrey:integer;
ch,prevchar:char;
Lineend:JString;
ind:Highlite;
Oneopen,Beginofline:boolean;
EFsnumber:JString;
allok:boolean;
columncorrect,indentlength,linecorrect:integer; //----------------------------------------------------------------- function Virtcolumn():integer; begin
Result:=RealColumn-columncorrect end; //----------------------------------------------------------------- function VirtLine():integer; begin
Result:=Line-linecorrect end; //----------------------------------------------------------------- procedure app(S:JString); var
i,LL:integer; begin if hasRepresentation thenbegin
Representation(S,streamout); end elsebegin
LL:=length(S); for i:=1 to LL do
streamout.WriteBuffer(S[i],1); end; end; //----------------------------------------------------------------- procedure CloseColor(); begin if ((Virtcolumn()>=NextColumn)or(ord(ch) in [Key_Return,Key_LineFeed])) and Oneopen thenbegin if Syntaxbold then
app(BoldOff+' ') else
app(SetNoColor+' ');
klzu:=klzu+1;
Oneopen:=false;
NextColumn:=99999; end end; //----------------------------------------------------------------- procedure Skipbeginofline(); var
rp:integer; begin
columncorrect:=0; //skip linefeed if ch=chr(Key_LineFeed) then
streamin.Read(ch,1); repeat if charinset(ch,[' ',chr(Key_Tab)]) then
columncorrect:=columncorrect-1 else
streamin.Position:=streamin.Position-1;
rp:=streamin.Read(ch,1); untilnot charinset(ch,[' ',chr(Key_Tab)])or(rp<0); end; //----------------------------------------------------------------- procedure ParAdd(); begin
CloseColor();
app(RtfParagraph);
app(chr(Key_Return)+chr(Key_LineFeed));
Line:=Line+1;
RealColumn:=1;
Beginofline:=true; end; //----------------------------------------------------------------- procedure makeIndent(); begin
indentlength:=TA.Y[Att].yyindent*indentchars; end; //----------------------------------------------------------------- procedure InsertIndent(); var
i:integer; begin if Beginofline thenbegin if doindent and(streamin.Position+1<streamin.Size) thenbegin for i:=indentlength downto 1 do
app(' ');
Skipbeginofline(); end;
Beginofline:=false; end; end; //----------------------------------------------------------------- procedure ArtificialLineBreaks(); begin //look for indent if Artificiallines and doindent and(Att>1) thenbegin if (TA.Y[Att].yylin=TA.Y[Att-1].yylin)and(TA.Y[Att-1].yyindent>0)and
(TA.Y[Att].yyindent>TA.Y[Att-1].yyindent) thenbegin //linecorrect:=linecorrect+1;
app(RtfParagraph);
app(chr(Key_Return)+chr(Key_LineFeed));
makeIndent();
Beginofline:=true;
InsertIndent();
Beginofline:=false; end; end; end; //----------------------------------------------------------------- begin
allok:=true;
EFsnumber:=IntToStr(getFileNumber(Efs));
Att:=1;
Line:=1;
RealColumn:=1;
NextColumn:=1;
Oneopen:=false;
lastgrey:=-1;
streamout.Position:=0;
streamin.Position:=0;
klauf:=0;
klzu:=0;
PlainText:=false;
Beginofline:=true;
app(RtfHeader());
streamin.Position:=0;
Lineend:='';
MaxColFound:=0;
MaxLineCount:=0;
Buffer:='';
Buffillled:=false;
Super:=false;
Sub:=false;
columncorrect:=0;
indentlength:=0;
linecorrect:=0;
prevchar:=chr(0); while (streamin.Read(ch,1)>0) dobegin
allok:=allok and printablechar(ch); ifnot allok then
allok:=false;
InsertIndent(); //must be > linefeed if (ord(ch)=Key_Return) thenbegin if Virtcolumn()>MaxColFound then
MaxColFound:=Virtcolumn();
MaxLineCount:=MaxLineCount+1;
ParAdd(); end elseif (ord(ch)=Key_LineFeed) thenbegin ifnot (prevchar=chr(Key_Return)) then
ParAdd(); if (klauf<>klzu) then
errorn(25,'zuviele Farbmarker in Zeile'+IntToStr(Line)); end elsebegin
CloseColor(); if SyntaxHighlight and(TA.AttrCount>0) thenbegin
makeIndent(); while (Att<TA.AttrCount)and(TA.Y[Att].yyfil<>EFsnumber) do
Att:=Att+1; while (Att<TA.AttrCount)and(TA.Y[Att].yylin<Line) do
Att:=Att+1; while (Att<TA.AttrCount)and(TA.Y[Att].yylin=Line)and
(TA.Y[Att].yycol<Virtcolumn()) do
Att:=Att+1; ifnot Oneopen and(Att<=TA.AttrCount)and(TA.Y[Att].yylin=VirtLine())and
(TA.Y[Att].yycol=Virtcolumn()) thenbegin if EFsnumber=TA.Y[Att].yyfil thenbegin
ArtificialLineBreaks();
NextColumn:=Virtcolumn()+TA.Y[Att].yylen;
klauf:=klauf+1; if Syntaxbold thenbegin if TA.Y[Att].yycolor=highlitekey[H_Keyword] then
app(Bold+' '); end elsebegin
app(SetColor);
ccol:=0; for ind:= Low(Highlite) toHigh(Highlite) do if TA.Y[Att].yycolor=highlitekey[ind] then
ccol:=ord(ind); if (ccol>=0)and(ccol<=ord( High(Highlite))) then
app(chr(ord('0')+ccol+1)) else
app('1');
app(' '); end;
Oneopen:=true;
Att:=Att+1; end; end; end; //correct strange codes if ch='\'then
app('\\') elseiford(ch)=Key_Tab then
app(ch) elseif ch='{'then
app('\{') elseif ch='}'then
app('\}') elseif ch<>' 'thenbegin
app(ch); end elseif (ch=' ') thenbegin if ShowSpaces thenbegin if (Virtcolumn()-1<>lastgrey)and(klauf=klzu) then
app(SetColor+'7'+'.') else
app('.');
lastgrey:=Virtcolumn() end else
app(ch); end else
app(ch);
RealColumn:=RealColumn+1; end;
prevchar:=ch; end;
app('}');
streamout.Position:=0;
Result:=allok; end; //------------------------------------------------------------------ //-- //load Attributes -- //-- //------------------------------------------------------------------ procedure TEde.LoadHighLites(Hi: arrayof TColor); var
h:Highlite;
o:integer;
C:TColor; begin for h:= low(Highlite) tohigh(Highlite) dobegin
o:=ord(h);
C:=Hi[o];
Highlites[h]:=C; end; end; //------------------------------------------------------------------ //-- //load Attributes -- //-- //------------------------------------------------------------------ procedure TEde.LoadAttributes(TC:PAnsiChar); var
S,SI:JString;
flen,rlen,i,j:integer;
CP,newlength:integer;
err:boolean;
lev,lastlev,offs:integer;
next,count:integer;
eofs:boolean;
Temp:TSingleAttribute; //------------------------------------------------------------------ //-- //open Stream/String -- //-- //------------------------------------------------------------------ procedure OpenStream(); begin
offs:=0;
eofs:=false; //Reset Stream
count:=0;
lev:=0;
lastlev:=0;//Reset Tree end; procedure GetNextRec(); begin
rlen:=offs;
next:=offs;
lastlev:=lev;
lev:=0; while (TC[next]=chr(9))and(next<=flen) dobegin
lev:=lev+1;
next:=next+1; end;
S:=''; while (TC[next]>chr(15))and(next<=flen) dobegin
S:=S+String(TC[next]);
next:=next+1; end;
rlen:=next-rlen;
eofs:=(TC=nil)or(TC='')or(TC[next]=chr(0))or(TC[next+1]=chr(0));
offs:=next+1;
count:=count+1; end; begin
TA.AttrCount:=0;
indentingpossible:=false;
flen:=length(TC); if (TC<>nil)and(flen>0) thenbegin
err:=false;
setlength(TA.Y,max(16,flen)); with TA dobegin
OpenStream(); repeat
GetNextRec(); if (AttrCount>=length(TA.Y)-1) thenbegin
newlength:=floor(AttrCount*3/2);
errorn(9,'Setze neue Länge Attributes');
setlength(TA.Y,newlength);
err:=true; end;
AttrCount:=AttrCount+1;
CP:=pos(',',S);
SI:=midstr(S,1,CP-1);
setl(Y[AttrCount].yyfil,SI);
S:=midstr(S,CP+1,length(S));
CP:=pos(',',S);
SI:=midstr(S,1,CP-1);
TryStrtoInt(SI,Y[AttrCount].yylin);
S:=midstr(S,CP+1,length(S));
CP:=pos(',',S);
SI:=midstr(S,1,CP-1);
TryStrtoInt(SI,Y[AttrCount].yycol);
S:=midstr(S,CP+1,length(S));
CP:=pos(',',S);
SI:=midstr(S,1,CP-1);
TryStrtoInt(SI,Y[AttrCount].yylen);
S:=midstr(S,CP+1,length(S));
CP:=pos(',',S);
SI:=midstr(S,1,CP-1);
setl(Y[AttrCount].yycolor,SI);
SI:=midstr(S,CP+1,length(S));
TryStrtoInt(SI,Y[AttrCount].yyindent);
indentingpossible:=indentingpossible or (Y[Attrcount].yyindent<>0); until eofs or err; //--------------------------------------- //sort the attributes, necessary //--------------------------------------- ifnot err then for i:=1 to TA.AttrCount-1 do for j:=i+1 to TA.AttrCount do if TA.Y[i].yylin*10000+TA.Y[i].yycol>TA.Y[j].yylin*10000+TA.Y[j]
.yycol thenbegin
Temp:=TA.Y[j];
TA.Y[j]:=TA.Y[i];
TA.Y[i]:=Temp end; end; end; end; //------------------------------------------------------------------------------ //-- //create RTF file -- //-- //------------------------------------------------------------------------------ procedure TEde.initLinearray(Anz:integer); var
i:integer; begin
Anz:=(Anz div 4)*4+8;
setlength(Blockarray.lines,Anz+1);
setlength(Linearray.lines,Anz+1);
Blockarray.count:=lines.count;
Linearray.count:=lines.count; for i:=1 to Anz do
Linearray.lines[i]:=i; end; //------------------------------------------------------------------------------ // //create RTF file -- //-- //------------------------------------------------------------------------------ function TEde.CreateHighlited(Nr:integer):TimeTripel; var
TimeSet:TDateTime;
Trtf,TEde,TLin,sels,sell:integer; begin
Screen.Cursor:=crHourGlass;
Trtf:=0;
TEde:=0;
TLin:=0;
sels:=SelStart;
sell:=SelLength;
reloading:=true; if length(Sources)>0 then try
Screen.Cursor:=crHourGlass; if (LoadedFile<>'')and(LoadedFile<>Sources[Nr]) then
Save(true);
clearstreams();
streamfile:=TFileStream.Create(Sources[Nr],fmShareDenyNone or fmOpenRead); //streamfile:=readFiletoStream(Sources[nr]);
streamatt:=TMemoryStream.Create();
streamatt.Position:=0;
TimeSet:=Now; ifnot SetRtfAttributes(Sources[Nr],streamfile,streamatt) thenbegin
inform(168,'Datei mit Binärdaten, angezeigt als ?','');
CreateBin(Nr); end elsebegin
Trtf:=MilliSecondsBetween(Now,TimeSet);
TimeSet:=Now; //---------------------------------------------------------- //set attributes //----------------------------------------------------------
ReadOnly:=false;
PlainText:=false;
WordWrap:=false;
ScrollBars:=ssBoth; if doindent then
SaveToUndoBuffer() else
clearUndoBuffer();
lines.Clear; //wichtig!!
MaxLength:=streamatt.Size+maxinputbuffer;
streamatt.Position:=0;
lines.LoadFromStream(streamatt);
TEde:=MilliSecondsBetween(Now,TimeSet);
TimeSet:=Now;
initLinearray(lines.count);
TLin:=MilliSecondsBetween(Now,TimeSet); //make sure positioning works
LoadedFile:=Sources[Nr];
LoadedFileNumber:=Nr;
LoadedFormat:=RTF; end;
settabs();
Modified:=doindent;
Screen.Cursor:=crDefault; except
On E:Exception do
CreateDummyFile(); end else
CreateDummyFile();
SelStart:=sels;
SelLength:=Sell;
Screen.Cursor:=crDefault;
Mark();
ReadOnly:=ShowSpaces;
Result.T1:=Trtf;
Result.T2:=TEde;
Result.T3:=TLin;
reloading:=false; end; //------------------------------------------------------------------------------ // //create RTF file -- //-- //------------------------------------------------------------------------------ procedure TEde.CreateRtfReadOnly(Nr:integer); var
lengthfile:integer;
isbin:boolean; begin
Screen.Cursor:=crHourGlass; if length(Sources)>0 then try
Screen.Cursor:=crHourGlass; //get content of file //---------------------------------------------------------- //set attributes //----------------------------------------------------------
ReadOnly:=false;
WordWrap:=true;
PlainText:=false; if dowordwrap thenbegin
WordWrap:=true;
ScrollBars:=ssVertical; end elsebegin
WordWrap:=false;
ScrollBars:=ssBoth; end; //wichtig!!
lengthfile:=getFileLength(Sources[Nr],isbin);
MaxLength:=lengthfile+maxinputbuffer;
lines.Clear;
clearUndoBuffer();
lines.LoadFromFile(Sources[Nr]);
initLinearray(lines.count); //make sure positioning works
LoadedFile:=Sources[Nr];
LoadedFileNumber:=Nr;
LoadedFormat:=RTF;
Modified:=false;
indentingpossible:=false;
Screen.Cursor:=crDefault; //SelStart:=0; //SelLength:=0;
ReadOnly:=true; except
On E:Exception do
CreateDummyFile(); end else
CreateDummyFile();
Mark();
settabs();
Screen.Cursor:=crDefault; end; //------------------------------------------------------------------------------ //-- //modify to show line numbers -- //-- //------------------------------------------------------------------------------ procedure TEde.Mark(); var
modif:boolean;
sell,sels:integer;
Indent,numberdigits:integer; begin
Screen.Cursor:=crHourGlass;
HideRedraw();
modif:=Modified;
ReadOnly:=false; //decide upon indent
Indent:=leastmargin;
numberdigits:=floor(log10(max(lines.count,1)))+1;
linemargin:=(numberdigits+1)*font.Size; if linemargin>leastmargin then if LineNumbers or Blocknumbers then
Indent:=linemargin; //SetFocus(); ifnot(LoadedFormat=Bin) thenbegin if (lines.count>=0) thenbegin
sels:=SelStart;
sell:=SelLength;
selectall();
Paragraph.Alignment:=taLeftJustify;
Paragraph.leftIndent:=Indent;
Paragraph.FirstIndent:=Indent; //now make numbers
makeLineBlockNumbers();
SelStart:=sels;
SelLength:=Sell; end; //done
Modified:=modif; end;
ShowRedraw();
Screen.Cursor:=crDefault; end; //------------------------------------------------------------------------------ //-- //create BIN file -- //-- //------------------------------------------------------------------------------ procedure TEde.CreateBin(Nr:integer); var
ch:ansichar;
Oneopen:boolean; //----------------------------------------------------------------- procedure app(S:JString); var
i,LL:integer; begin
LL:=length(S); for i:=1 to LL do
streamatt.WriteBuffer(S[i],1); end; //----------------------------------------------------------------- procedure ParAdd(); begin
app(SetNoColor+' ');
Oneopen:=false;
app(RtfParagraph);
app(chr(Key_Return)+chr(Key_LineFeed)); end; //----------------------------------------------------------------- begin
reloading:=true; if FileExists(Sources[Nr]) thenbegin if (LoadedFile<>'')and(LoadedFile<>Sources[Nr]) then
Save(true);
ReadOnly:=false;
PlainText:=true;
WordWrap:=true;
ScrollBars:=ssVertical; //
streamfile:=TFileStream.Create(Sources[Nr],fmOpenRead or fmShareDenyWrite);
streamatt:=TMemoryStream.Create();
streamfile.Position:=0;
streamatt.Position:=0; //prepare
lines.Clear;
clearUndoBuffer();
MaxLength:=(3*streamfile.Size)div 2; //add chars while streamfile.Read(ch,1)>0 dobegin if (ch<' ') then
app('?') else
app(ch); end;
streamatt.Position:=0;
lines.LoadFromStream(streamatt);
initLinearray(lines.count);
LoadedFile:=Sources[Nr];
LoadedFileNumber:=Nr;
LoadedFormat:=Bin;
Mark();
Modified:=false;
ReadOnly:=true;
indentingpossible:=false; end elsebegin
CreateDummyFile(); end;
Modified:=false;
reloading:=false; end; //------------------------------------------------------------------------------ //-- //create RTF file -- //-- //------------------------------------------------------------------------------ procedure TEde.CreatePlain(Nr:integer); var
isbin:boolean;
FE:JString; begin
reloading:=true; if FileExists(Sources[Nr]) thenbegin if (LoadedFile<>'')and(LoadedFile<>Sources[Nr]) then
Save(true);
ReadOnly:=false;
font.Color:=clBlack; if dowordwrap thenbegin
WordWrap:=true;
ScrollBars:=ssVertical; end elsebegin
WordWrap:=false;
ScrollBars:=ssBoth; end;
PlainText:=true; //wichtig!! Sonst gibt es Murks im RichEditor
lines.Clear;
FE:=ExtractFileExt(Sources[Nr]);
MaxLength:=getFileLength(Sources[Nr],isbin)+maxinputbuffer; ifnot isbin thenbegin
streamfile:=TFileStream.Create(Sources[Nr],
fmOpenRead or fmShareDenyWrite);
lines.LoadFromStream(streamfile);
clearUndoBuffer();
initLinearray(lines.count);
LoadedFile:=Sources[Nr];
LoadedFileNumber:=Nr;
LoadedFormat:=Plain;
indentingpossible:=false;
Mark(); end else
CreateBin(Nr); end elsebegin
CreateDummyFile(); end;
settabs();
Modified:=false;
reloading:=false; end; //------------------------------------------------------------------------------ //-- //create RTF file -- //-- //------------------------------------------------------------------------------ procedure TEde.CreateString(Stdout,Stderr:JString); begin
reloading:=true;
Save(true);
ReadOnly:=false;
PlainText:=true;
lines.Clear; //wichtig!! Sonst gibt es Murks im RichEditor
MaxLength:=length(Stdout)+length(Stderr)+maxinputbuffer;
WordWrap:=false;
ScrollBars:=ssBoth;
lines.Clear;
clearUndoBuffer();
font.Color:=clBlue;
DefAttributes.Color:=clBlue;
SelAttributes.Color:=clBlue;
lines.Add(Stdout);
lines.Add(Stderr);
initLinearray(lines.count);
LoadedFile:='';
LoadedFileNumber:=0;
LoadedFormat:=Plain;
indentingpossible:=false;
Mark();
ReadOnly:=true;
Modified:=false;
reloading:=false; end; //------------------------------------------------------------------ //-- //flush streams -- //-- //------------------------------------------------------------------ procedure TEde.clearstreams(); begin
flushstreams(); if streamfile<>nilthen
streamfile.Free; if streamatt<>nilthen
streamatt.Free; if streamorig<>nilthen
streamorig.Free;
streamfile:=nil;
streamatt:=nil;
streamorig:=nil; end; //------------------------------------------------------------------ //-- //flush streams -- //-- //------------------------------------------------------------------ procedure TEde.flushstreams(); begin if (streamfile<>nil) then
FlushFileBuffers(streamfile.Handle); end; //------------------------------------------------------------------ //-- //save Sources to file -- //-- //------------------------------------------------------------------ function TEde.Save(askhim:boolean):integer; const
Rev='_r'; var
doit:boolean;
Nam,Path,Ext,Sav:JString;
P,r1,r2,T,Revisions:integer;
mresult:integer; begin
doit:=not askhim;
mresult:=mrYes; ifnot ShowSpaces and Modified thenbegin if LoadedFile=''then
doit:=false elseif askhim thenbegin
mresult:=ask(30,'Datei Sichern?',
ExtractFileName(ExtractFileName(LoadedFile)));
doit:=mresult=mrYes; end; if doit ornot askhim thenbegin //first flush buffers!!
flushstreams(); if (LoadedFile<>'')and CreateBackup thenbegin //saves to history
Nam:=ExtractFileName(LoadedFile);
Path:=ExtractFilePath(LoadedFile)+'history\';
Ext:=ExtractFileExt(Nam); ifnot DirectoryExists(Path) then
CreateDir(Path);
P:=pos('.',Nam)-1;
Nam:=midstr(Nam,1,P);
r1:=pos(Rev,Nam);
r2:=length(Nam)-r1-1; if (r1>0)and(r2>0) thenbegin
T:=0;
TryStrtoInt(midstr(Nam,r1+2,r2),T);
Revisions:=T;
Nam:=midstr(Nam,1,r1-1); end else
Revisions:=0; repeat
Revisions:=Revisions+1;
Sav:=Path+Nam+Rev+IntToStr(Revisions)+Ext; untilnot FileExists(Sav);
streamorig:=TFileStream.Create(LoadedFile,
fmOpenRead or fmShareDenyNone);
streamorig.Position:=0;
streamfile:=TFileStream.Create(Sav,fmCreate);
streamfile.CopyFrom(streamorig,streamorig.Size); end;
PlainText:=true; //streamfile is still open, so //exchange contents of streamfile by freeing and reloading
streamfile.Free;
streamfile:=TFileStream.Create(LoadedFile,fmOpenWrite+fmShareDenyWrite);
streamfile.Position:=0;
streamfile.Size:=0;
lines.SaveToStream(streamfile);
Modified:=false end end elseif Modified and ShowSpaces thenbegin
mresult:=mrNo;
inform(32,'bitte zuerst Leerzeichen ausschalten',''); end;
Result:=mresult end; //------------------------------------------------------------------------------ //-- //a dummy file -- //-- //------------------------------------------------------------------------------ procedure TEde.CreateDummyFile(); begin //Setlength(Blockarray,1024);
Clear;
lines.Add('');
lines.Add('');
lines.Add(trans(lang,226,' Sage nicht immer, was Du weißt,'));
lines.Add(trans(lang,227,' aber wisse immer, was Du sagst.'));
lines.Add('');
lines.Add(' Matthias Claudius');
Mark();
LoadedFile:='';
indentingpossible:=false;
LoadedFormat:=Plain;
ReadOnly:=true;
PlainText:=true; end; //----------------------------------------------------------------- //catch messages of zeilennummern //----------------------------------------------------------------- procedure TEde.makeLineBlockNumbers(); var
hdc:THandle;
CurRect:TRect;
modif:boolean;
readon:boolean; function getmark(L:integer):String; var
S:String;
i:integer; begin if Blocknumbers thenbegin if (Blockarray.count>L) thenbegin
S:=' '; if Blockarray.lines[L]>0 then
S:=midstr(' '+Format('[%d]',[Blockarray.lines[L]])+' ',1,6) end end elsebegin
S:=Format('%6.6d',[L]);
i:=1; while i<6 dobegin if S[i]='0'then
S[i]:=' ' else
i:=6;
i:=i+1 end; end;
getmark:=midstr(S,1,6); end; procedure makethem(); var
LineChar,LineNumber,MaxNumberofLines,FirstVisibleLine:integer;
LineMark:JString;
P:TPoint;
ForeG,BackG:TColor; begin
MaxNumberofLines:=getNumberofVisibleLines();
FirstVisibleLine:=getFirstVisibleLine();
ForeG:=RGB(164,164,164);
BackG:=RGB(255,255,255);
SetTextColor(hdc,ForeG);
SetBkColor(hdc,BackG); for LineNumber:=FirstVisibleLine-1 to FirstVisibleLine+MaxNumberofLines-1 dobegin
LineChar:=getCharIndexfromLine(LineNumber); if LineChar<>-1 thenbegin
LineMark:=getmark(LineNumber+1);
P:=getDotFromChar(LineChar); with CurRect dobegin
left:=0;
right:=linemargin;
top:=P.Y;
bottom:=getRectBottom(); end;
DrawText(hdc,pwidechar(LineMark),length(LineMark),&CurRect,DT_RIGHT); end; end; end; begin
hdc:=GetDC(Handle); ifnot(LoadedFormat=Bin)and(hdc<>0)and(getScrollPos().X=0)and
(LineNumbers or Blocknumbers) thenbegin
modif:=Modified;
readon:=ReadOnly;
ReadOnly:=false;
makethem();
ReadOnly:=readon;
Modified:=modif; end;
ReleaseDC(Handle,hdc); end; //------------------------------------------------------------------ //-- //on key down in Sources -- //-- //------------------------------------------------------------------ procedure TEde.searchreplace(Kind:SeaRepFun); var
fin:TRegInfo;
FoundText,ReplaceText:JString; procedure SearchAndReplace(var X:integer;InSearch:JString); begin if FoundAt>=0 thenbegin if regexpsearch thenbegin if (InSearch='^') thenbegin//only ^
X:=fin.pos;
FoundText:='' end elseif (InSearch='$') thenbegin//only $
X:=fin.pos;
FoundText:=chr(Key_Return) end elsebegin
X:=fin.pos;
FoundText:=GetTextRange(fin.pos,fin.pos+fin.len-1); end; end elsebegin
X:=SelStart;
FoundText:=Seltext; end;
SetFocus;
SelStart:=X;
SelLength:=length(FoundText);
ReplaceText:=StringReplace(ReplaceString.S,'\0',FoundText,[rfReplaceAll]);
Seltext:=ReplaceText; end; end; begin
FoundAt:=-1; if Kind in [FuncSearch,FuncReplace,FuncContReplace] thenbegin if (SearchString.S='') then
setl(SearchString.S,Seltext); if (SearchString.S>'') thenbegin
fin:=findsingle(SelStart);
FoundAt:=fin.pos;
Wrapped:=false; if FoundAt<0 then
Wrapped:=true; if (FoundAt>=0) then
Perform(EM_SETSEL,fin.pos,fin.pos+fin.len); //replace the string? if Kind<>FuncSearch then
SearchAndReplace(FoundAt,SearchString.S); end; end; end; //------------------------------------------------------------------------------ //-- //correct after insert delete -- //-- //------------------------------------------------------------------------------ procedure TEde.PositioningCorrect(from,num:integer); var
i,Anz,newfrom,oldcount:integer;
lineold,blockold: arrayofinteger; begin //insert erfolgt if lines.count>Linearray.count thenbegin //save state //allocate buffer
oldcount:=Linearray.count;
Anz:=(4*lines.Count) div 4 + 4;
setlength(lineold,Anz);
setlength(blockold,Anz); for i:=1 to oldcount dobegin
lineold[i]:=Linearray.lines[i];
blockold[i]:=Blockarray.lines[i] end; //allocate new
Anz:=(4*lines.count) div 4*+4;
setlength(Blockarray.lines,Anz);
setlength(Linearray.lines,Anz);
Blockarray.count:=lines.count;
Linearray.count:=lines.count; //initialize for i:=1 to Anz-1 dobegin
Linearray.lines[i]:=i;
Blockarray.lines[i]:=i end; //transfer to new for i:=1 to oldcount dobegin
Linearray.lines[i]:=lineold[i];
Blockarray.lines[i]:=blockold[i] end; //now correct
newfrom:=from;
i:=0; while i<Linearray.count dobegin if Linearray.lines[i]=from then
newfrom:=i;
i:=i+1; end;
from:=newfrom; //num:=newnum; for i:=from to Linearray.count-num dobegin
Linearray.lines[i]:=Linearray.lines[i+num];
Blockarray.lines[i]:=Blockarray.lines[i+num]; end; end //cut erfolgt elseif lines.count<Linearray.count thenbegin for i:=Linearray.count downto from-num dobegin
Linearray.lines[i]:=Linearray.lines[i-num];
Blockarray.lines[i]:=Blockarray.lines[i-num]; end; end; end; //------------------------------------------------------------------------------ // //save RTF file nonexlusively -- //-- //------------------------------------------------------------------------------ procedure TEde.SaveRtfTo(S:JString); var
Orig:TFileStream; begin
Orig:=nil; try
flushstreams(); if FileExists(S) then
Orig:=TFileStream.Create(S,fmOpenWrite+fmShareDenyNone) else
Orig:=TFileStream.Create(S,fmCreate); except
errorn(11,'Datei kann nicht angelegt werden:'+S); end; if Orig<>nilthenbegin
lines.SaveToStream(Orig);
Orig.Free; end; end; //----------------------------------------------------------------- //show redraw //----------------------------------------------------------------- procedure TEde.ShowRedraw(); begin
Perform(WM_SETREDRAW,Wparam(true),0);
Repaint; end; //----------------------------------------------------------------- //show redraw //----------------------------------------------------------------- procedure TEde.HideRedraw(); begin
Perform(WM_SETREDRAW,Wparam(false),0); end; //----------------------------------------------------------------- //filter messages of Sources //----------------------------------------------------------------- procedure TEde.OnMouseDbl(var Message:TMessage); var
LL:integer;
Filnam:JString; Begin
getCurrentWord(); if CurrentWord>''thenbegin
Filnam:=ExtractFilePath(LoadedFile)+CurrentWord; if FileExists(Filnam) thenbegin
LL:=length(Sources);
setlength(Sources,LL+1);
Sources[LL]:=Filnam;
CreatePlain(LL); end; end; End; //----------------------------------------------------------------- //filter messages of Sources //----------------------------------------------------------------- procedure TEde.OnMouse(var Message:TMessage); Begin if CodeCompleter.Visible then
CodeCompleter.setInvisible(); End; //----------------------------------------------------------------- //filter messages of Sources //----------------------------------------------------------------- procedure TEde.OnKey(var Message:TMessage); var
KeyState:TKeyboardState;
Key,LL:integer; Begin
Indenting(Message);
GetKeyboardState(KeyState);
Key:=Message.Wparam; //Ctrl:=KeyState[VK_CONTROL]; //Shift:=KeyState[VK_SHIFT]; if Key in [VK_SPACE,VK_RETURN,VK_BACK,VK_CLEAR,VK_DELETE] then
SaveToUndoBuffer() elseif (Key=VK_DOWN) thenbegin
LL:=getLinefromCharIndex(SelStart); if LL+1=lines.count thenbegin
lines.Add('');
SelStart:=length(lines.Text);
SelLength:=0; end; end; if Key in [VK_RETURN,VK_BACK,VK_DELETE] then
PositioningCorrect(CaretPos.Y,1); End; //----------------------------------------------------------------- //filter messages of Sources //----------------------------------------------------------------- procedure TEde.Indenting(var Message:TMessage); var
Indent:JString;
P,LL,i:integer;
found:boolean;
ch:char;
prefix:JString; begin if (message.Wparam=Key_Enter)and(Message.Msg=WM_KEYUP) thenbegin
P:=CaretPos.Y; //calculate Indent
i:=1;
Indent:=''; if (InputFormat=FixedFormat) thenbegin
Indent:=' ';
i:=7; end;
LL:=length(lines[P-1]); while (i<=LL) dobegin if (lines[P-1][i]=' ') then
Indent:=Indent+' ' else
i:=length(lines[P-1])+1;
i:=i+1; end; //take care of leading Blanks
i:=1;
found:=false;
prefix:=''; while (i<=length(lines[P]))andnot found dobegin
ch:=lines[P][i]; if (ch<>' ') then
found:=true; ifnot found then
prefix:=prefix+ch;
i:=i+1 end;
LL:=length(prefix); if LL>=length(Indent) then
Indent:='' else
Indent:=midstr(Indent,LL+1,length(Indent)); //end leading blanks
lines[P]:=Indent+lines[P]; end; end; //----------------------------------------------------------------- //filter messages of Sources //----------------------------------------------------------------- procedure TEde.WindProc(var Message:TMessage); begin
oldwinproc(Message); ifnot(reloading or(csDesigning in ComponentState)) thenbegin if Message.Msg=CN_NOTIFY then
CNNotify(Message) //else if (Message.WParamHi=EN_UPDATE)or(Message.WParamHi=EN_VSCROLL)or //(Message.Msg=WM_VSCROLL) elseif (Message.Msg=WM_PAINT) then
makeLineBlockNumbers(); case Message.Msg of
WM_LBUTTONDOWN,WM_RBUTTONDOWN:
OnMouse(Message);
WM_LBUTTONDBLCLK:
OnMouseDbl(Message);
WM_KEYDOWN:
OnKey(Message); end; end end; //------------------------------------------------------------------ // //------------------------------------------------------------------ function TEde.getCharat(pos:integer):char; var
tr:textrange;
res:JString;
C:char; begin
C:=chr(0); if pos<length(lines.Text) thenbegin with tr dobegin
chrg.cpMin:=pos;
chrg.cpMax:=pos+1;
GetMem(lpstrText,8); end;
SendMessage(Handle,EM_GETTEXTRANGE,0,integer(@tr));
res:=tr.lpstrText; if tr.lpstrText>''then
C:=res[1]; end;
getCharat:=C end; //------------------------------------------------------------------ //similar solution, untested //------------------------------------------------------------------ function TEde.GetTextRange(BeginPos,EndPos:integer):String; var
tr:textrange;
MaxLength:integer; begin
MaxLength:=EndPos-BeginPos+1; if MaxLength>0 thenbegin
setlength(Result,MaxLength); with tr dobegin
chrg.cpMin:=BeginPos;
chrg.cpMax:=BeginPos+MaxLength;
lpstrText:=PChar(Result); end;
setlength(Result,SendMessage(Handle,EM_GETTEXTRANGE,0,LongInt(@tr))); end else
Result:=''; end; //------------------------------------------------------------------ //-- //mark brackets -- //-- //------------------------------------------------------------------ procedure TEde.Bracketing(); const
bro=['(','[','{'];
brc=[')',']','}']; var
sel,Orig:integer;
modif:boolean;
C:widechar; procedure brackdel(P:integer); begin if P>0 thenbegin
markLinePos(P,1);
SelAttributes.Color:=clBlue;
SelAttributes.Style:=SelAttributes.Style-[fsbold,fsUnderline]; end; end; procedure brackmark(P:integer); begin if P>0 thenbegin
markLinePos(P,1);
SelAttributes.Color:=clBlue;
SelAttributes.Style:=SelAttributes.Style+[fsbold,fsUnderline];
Refresh; end; end; procedure brackclear(ofs:integer); var
i,op:integer;
found:boolean; begin if ofs=1 thenbegin
i:=SelStart+2;
op:=1 end elsebegin
i:=SelStart;
op:=-1; end;
found:=false; while (i>0)and(i<length(lines.Text))and(not found) dobegin
C:=getCharat(i); if charinset(C,bro) then
op:=op+1; if charinset(C,brc) then
op:=op-1; if ofs=1 then
found:=op<=0 else
found:=op>=0;
i:=i+ofs; end; if (op=0) thenbegin if ofs=1 then
markLinePos(i-2,1) else
markLinePos(i,1);
brack2:=SelStart;
brackmark(SelStart); end; end; begin ifnot(csDesigning in ComponentState)and(SelStart<length(lines.Text))and
(SelStart>=0)and(SelStart<length(lines.Text)) thenbegin
C:=getCharat(SelStart); if charinset(C,bro)or charinset(C,brc) thenbegin
modif:=Modified;
Orig:=SelStart;
sel:=SelStart;//+1
brackdel(brack1);
brackdel(brack2);
brack1:=0;
brack2:=0;
C:=getCharat(sel); if charinset(C,bro) thenbegin
brack1:=sel-1;
brackmark(sel-1);
brackclear(1); end elseif charinset(C,brc) thenbegin
brack1:=sel-1;
brackmark(sel-1);
brackclear(-1); end elsebegin
brack1:=0;
brack2:=0; end;
markLinePos(Orig,1);
Modified:=modif; end; end; end; //------------------------------------------------------------------ //-- //posit Editor -- //-- //------------------------------------------------------------------ procedure TEde.PositEditor; begin if Visible then
SetFocus; if Visible and Focused thenbegin
setSearchString(' ',false);
setCharPos(findsingle(0).pos,1); end; end; //------------------------------------------------------------------ //Scroller -- //-- //------------------------------------------------------------------ procedure TEde.Scroller(WheelDelta:integer); var
samount:integer;
iX,iY,i:integer; procedure GetPosition; begin
iX:=0;
iY:=0;
iY:=SendMessage(Handle,EM_LINEFROMCHAR,SelStart,0)+1;
iX:=SelStart-SendMessage(Handle,EM_LINEINDEX,iY,0)+1; end; begin if WheelDelta>0 then
samount:=SB_LINEUP else
samount:=SB_LINEDOWN;
GetPosition; if (iY>0)and(iY<lines.count-font.Size) then for i:=1 to font.Size do
SendMessage(Handle,EM_SCROLL,samount,0); end; //----------------------------------------------------------------- //produce Header for rtf file - //- //------------------------------------------------------------------ function TEde.RtfHeader():AnsiString; var
Header,ColorTable,Isar:AnsiString;
h:Highlite;
C:TColor;
RGB,R,g,b:integer; begin //check for ISabelle Font (Elbian is a corrected copy)
Isar:='Elbian'; if hasRepresentation then ifnot FileExists('\windows\fonts\Elbian.ttf') thenbegin
errorn(110,'Elbian Font fehlt, bitte installieren.');
Isar:='Courier New'; end; //set rtf header
Header:=AnsiString('{\rtf1\ansi\ansicpg850 \deff0'+'{\fonttbl'+'{\f0\fnil ')
+AnsiString(font.name)+AnsiString(';}'+'{\f1\fnil ')+AnsiString(font.Name)
+';}'+AnsiString('{\f2\fnil '+Isar+';}'+'}');
ColorTable:='{\colortbl;'; for h:= low(Highlite) tohigh(Highlite) dobegin
C:=Highlites[h];
RGB:=ColorToRGB(C);
b:=RGB mod 256;
RGB:=RGB div 256;
g:=RGB mod 256;
RGB:=RGB div 256;
R:=RGB;
ColorTable:=ColorTable+AnsiString('\red'+IntToStr(R));
ColorTable:=ColorTable+AnsiString('\green'+IntToStr(g));
ColorTable:=ColorTable+AnsiString('\blue'+IntToStr(b));
ColorTable:=ColorTable+';'; end;
ColorTable:=ColorTable+'}';
Header:=Header+crlf+ColorTable;
Header:=Header+AnsiString(SetSize+IntToStr(font.Size*2)+' '+crlf);
RtfHeader:=Header end; //----------------------------------------------------------------- // //CNNotify, TRichEditURL //message CN_NOTIFY // //----------------------------------------------------------------- procedure TEde.CNNotify(var Msg:TMessage); var
tm:TWMNotify;
P:TENLink; procedure Browser(Handle:cardinal;URL:JString); begin
Screen.Cursor:=crHourGlass;
ShellExecute(Handle,'open',PChar(URL),nil,'',SW_SHOWNORMAL);
sleep(2000);
Screen.Cursor:=crDefault; end; begin
tm:=TWMNotify(Msg); if (tm.NMHdr^.code=EN_LINK) thenbegin
P:=TENLink(Pointer(tm.NMHdr)^); if (P.Msg=WM_LBUTTONDOWN) thenbegin try
SendMessage(Handle,EM_EXSETSEL,0,LongInt(@(P.chrg)));
Browser(Handle,Seltext); except end; end; end; inherited; end; //----------------------------------------------------------------- //- //createWnd URL - //- //----------------------------------------------------------------- procedure TEde.CreateWnd; var
mask:DWORD; begin inherited CreateWnd; if showURL then
SendMessage(Handle,EM_AUTOURLDETECT,1,0) else
SendMessage(Handle,EM_AUTOURLDETECT,0,0);
mask:=SendMessage(Handle,EM_GETEVENTMASK,0,0);
SendMessage(Handle,EM_SETEVENTMASK,0,mask or ENM_LINK); end; //------------------------------------------------------------------ //-- //Ende dieser Quelle -- //-- //------------------------------------------------------------------ end.
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.63 Sekunden
(vorverarbeitet am 2026-04-26)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.