mysticbbs/mystic/bbs_edit_ansi.pas

1500 lines
39 KiB
ObjectPascal
Raw Normal View History

2012-02-15 21:39:34 -08:00
Unit bbs_Edit_Ansi;
{$I M_OPS.PAS}
2013-03-07 07:39:10 -08:00
Interface
2013-03-04 07:53:06 -08:00
Uses
2013-03-22 20:17:33 -07:00
m_FileIO,
2013-08-29 03:04:20 -07:00
BBS_MsgBase_Ansi;
2013-03-04 07:53:06 -08:00
2013-03-30 03:37:08 -07:00
Const
fseMaxCutText = 60;
2013-08-30 21:38:55 -07:00
GlyphTypeMax = 10;
2013-09-16 13:31:39 -07:00
GlyphTypeStr : Array[1..10] of String[10] = (
2013-08-30 21:38:55 -07:00
('<27>ڿ<EFBFBD><DABF>ijô<C4B3>'),
('<27>ɻȼͺ̹<CDBA>'),
('<27>ոԾͳƵ<CDB3>'),
('<27>ַӽĺǶ<C4BA>'),
('<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>'),
('<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>'),
('<06> '),
(''),
('<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>'),
('<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>')
);
2013-03-04 07:53:06 -08:00
Type
TEditorANSI = Class
2013-03-22 20:17:33 -07:00
Owner : Pointer;
ANSI : TMsgBaseANSI;
WinY1 : Byte;
WinY2 : Byte;
WinX1 : Byte;
WinX2 : Byte;
WinSize : Byte;
RowSize : Byte;
CurX : Byte;
CurY : SmallInt;
CurAttr : Byte;
2013-03-23 08:22:51 -07:00
QuoteAttr : Byte;
2013-03-22 20:17:33 -07:00
CurLength : Byte;
TopLine : LongInt;
CurLine : LongInt;
InsertMode : Boolean;
DrawMode : Boolean;
GlyphMode : Boolean;
2013-08-30 21:38:55 -07:00
GlyphPtr : Byte;
2013-03-22 20:17:33 -07:00
WrapMode : Boolean;
ClearEOL : Boolean;
LastLine : LongInt;
QuoteTopPage : SmallInt;
QuoteCurLine : SmallInt;
2013-03-30 03:37:08 -07:00
CutText : Array[1..fseMaxCutText] of RecAnsiBufferLine;
CutTextPos : Word;
CutPasted : Boolean;
2013-04-01 13:22:22 -07:00
Save : Boolean;
Forced : Boolean;
Done : Boolean;
Subject : String;
2013-05-06 10:19:01 -07:00
Template : String;
2013-08-30 21:38:55 -07:00
DrawTemplate : String;
SavedInsert : Boolean;
2013-05-09 01:38:41 -07:00
MaxMsgLines : Word;
MaxMsgCols : Byte;
2013-03-04 07:53:06 -08:00
2013-05-06 10:19:01 -07:00
Constructor Create (Var O: Pointer; TemplateFile: String);
2013-03-04 07:53:06 -08:00
Destructor Destroy; Override;
Function IsAnsiLine (Line: LongInt) : Boolean;
Function IsBlankLine (Var Line; LineSize: Byte) : Boolean;
Function GetLineLength (Var Line; LineSize: Byte) : Byte;
Function GetWrapPos (Var Line; LineSize, WrapPos: Byte) : Byte;
2013-03-22 20:17:33 -07:00
Procedure TrimLeft (Var Line; LineSize: Byte);
2013-03-30 03:37:08 -07:00
Procedure TrimRight (Var Line; LineSize: Byte);
2013-03-04 07:53:06 -08:00
Procedure DeleteLine (Line: LongInt);
Procedure InsertLine (Line: LongInt);
2013-03-07 07:39:10 -08:00
Function GetLineText (Line: Word) : String;
Procedure SetLineText (Line: LongInt; Str: String);
2013-03-04 07:53:06 -08:00
Procedure FindLastLine;
2013-03-30 03:37:08 -07:00
Procedure WordWrap;
Procedure ReformParagraph;
2013-03-04 07:53:06 -08:00
Procedure LocateCursor;
2013-03-22 20:17:33 -07:00
Procedure ToggleInsert (Toggle: Boolean);
Procedure ReDrawTemplate (Reset: Boolean);
2013-03-04 07:53:06 -08:00
Procedure DrawPage (StartY, EndY: Byte; ExitEOF: Boolean);
Procedure ScrollUp;
2013-03-22 20:17:33 -07:00
Procedure ScrollDown (Draw: Boolean);
2013-03-31 22:08:13 -07:00
Function LineUp (Reset: Boolean) : Boolean;
2013-03-04 07:53:06 -08:00
Function LineDown (Reset: Boolean) : Boolean;
Procedure PageUp;
Procedure PageDown;
Procedure DrawLine (Line: LongInt; XP, YP: Byte);
Procedure DoEnter;
Procedure DoBackSpace;
Procedure DoDelete;
Procedure DoChar (Ch: Char);
Function Edit : Boolean;
2013-04-01 13:22:22 -07:00
Procedure Quote;
Procedure QuoteWindow;
2013-08-30 21:38:55 -07:00
Procedure EditorCommands;
Procedure DrawCommands;
2013-04-01 13:22:22 -07:00
Procedure MessageUpload;
2013-03-04 07:53:06 -08:00
End;
2012-02-15 21:39:34 -08:00
Implementation
2013-03-04 07:53:06 -08:00
Uses
m_Strings,
2013-08-29 03:04:20 -07:00
BBS_Records,
BBS_Core,
BBS_Ansi_MenuBox;
2013-03-04 07:53:06 -08:00
2013-05-06 10:19:01 -07:00
Constructor TEditorANSI.Create (Var O: Pointer; TemplateFile: String);
2013-03-04 07:53:06 -08:00
Begin
Inherited Create;
2013-05-09 01:38:41 -07:00
Owner := O;
ANSI := TMsgBaseANSI.Create(NIL, False);
WinX1 := 1;
WinX2 := 79;
WinY1 := 2;
WinY2 := 23;
WinSize := WinY2 - WinY1 + 1;
RowSize := WinX2 - WinX1 + 1;
CurX := 1;
CurY := 1;
CurLine := 1;
TopLine := 1;
CurAttr := 7;
QuoteAttr := 9;
InsertMode := True;
DrawMode := False;
GlyphMode := False;
2013-08-30 21:38:55 -07:00
GlyphPtr := 6;
2013-05-09 01:38:41 -07:00
WrapMode := True;
ClearEOL := RowSize >= 79;
LastLine := 1;
CutPasted := False;
CutTextPos := 0;
Template := TemplateFile;
MaxMsgLines := mysMaxMsgLines;
MaxMsgCols := 79;
2013-03-30 03:37:08 -07:00
FillChar (CutText, SizeOf(CutText), 0);
2013-03-04 07:53:06 -08:00
End;
Destructor TEditorANSI.Destroy;
Begin
Inherited Destroy;
ANSI.Free;
End;
2013-03-07 07:39:10 -08:00
Function TEditorANSI.GetLineText (Line: Word) : String;
Var
Count : Word;
Begin
Result := '';
For Count := 1 to GetLineLength(ANSI.Data[Line], RowSize) Do
2013-04-06 20:58:41 -07:00
If ANSI.Data[Line][Count].Ch = #0 Then
Result := Result + ' '
Else
Result := Result + ANSI.Data[Line][Count].Ch;
2013-03-07 07:39:10 -08:00
End;
Procedure TEditorANSI.SetLineText (Line: LongInt; Str: String);
Var
Count : Byte;
Begin
FillChar (ANSI.Data[Line], SizeOf(ANSI.Data[Line]), 0);
For Count := 1 to Length(Str) Do Begin
ANSI.Data[Line][Count].Ch := Str[Count];
ANSI.Data[Line][Count].Attr := CurAttr;
End;
End;
2013-03-04 07:53:06 -08:00
Procedure TEditorANSI.FindLastLine;
Begin
2013-05-09 01:38:41 -07:00
LastLine := MaxMsgLines;
2013-03-04 07:53:06 -08:00
While (LastLine > 1) And IsBlankLine(ANSI.Data[LastLine], 80) Do
Dec(LastLine);
End;
Function TEditorANSI.IsAnsiLine (Line: LongInt) : Boolean;
Var
Count : Byte;
Begin
Result := False;
If GetLineLength(ANSI.Data[Line], 80) >= Rowsize Then Begin
Result := True;
Exit;
End;
For Count := 1 to 80 Do
If (Ord(ANSI.Data[Line][Count].Ch) < 32) or (Ord(ANSI.Data[Line][Count].Ch) > 128) Then Begin
Result := True;
Exit;
End;
End;
Function TEditorANSI.IsBlankLine (Var Line; LineSize: Byte) : Boolean;
Var
EndPos : Byte;
Data : Array[1..255] of RecAnsiBufferChar absolute Line;
Begin
EndPos := LineSize;
While (EndPos > 0) and (Data[EndPos].Ch = #0) Do
Dec (EndPos);
Result := EndPos = 0;
End;
2013-03-22 20:17:33 -07:00
Procedure TEditorANSI.TrimLeft (Var Line; LineSize: Byte);
2013-03-04 07:53:06 -08:00
Var
Data : Array[1..255] of RecAnsiBufferChar absolute Line;
EndPos : Byte;
Begin
EndPos := 1;
While (EndPos <= LineSize) and (Data[1].Ch = ' ') Do Begin
Move (Data[2], Data[1], SizeOf(RecAnsiBufferChar) * (LineSize - 1));
Data[LineSize].Ch := #0;
Inc (EndPos);
End;
End;
2013-03-30 03:37:08 -07:00
Procedure TEditorANSI.TrimRight (Var Line; LineSize: Byte);
Var
Data : Array[1..255] of RecAnsiBufferChar absolute Line;
Begin
While ((Data[LineSize].Ch = ' ') or (Data[LineSize].Ch = #0)) Do Begin
Data[LineSize].Ch := #0;
Dec (LineSize);
End;
End;
2013-03-04 07:53:06 -08:00
Procedure TEditorANSI.DeleteLine (Line: LongInt);
Var
Count : LongInt;
Begin
2013-05-09 01:38:41 -07:00
For Count := Line to MaxMsgLines - 1 Do
2013-03-04 07:53:06 -08:00
ANSI.Data[Count] := ANSI.Data[Count + 1];
2013-05-09 01:38:41 -07:00
FillChar (ANSI.Data[MaxMsgLines], SizeOf(RecAnsiBufferLine), #0);
2013-03-04 07:53:06 -08:00
If LastLine > 1 Then Dec(LastLine);
End;
Procedure TEditorANSI.InsertLine (Line: LongInt);
Var
Count : LongInt;
Begin
2013-05-09 01:38:41 -07:00
For Count := MaxMsgLines DownTo Line + 1 Do
2013-03-04 07:53:06 -08:00
ANSI.Data[Count] := ANSI.Data[Count - 1];
FillChar(ANSI.Data[Line], SizeOf(RecAnsiBufferLine), #0);
2013-05-09 01:38:41 -07:00
If LastLine < MaxMsgLines Then Inc(LastLine);
2013-03-04 07:53:06 -08:00
End;
Function TEditorANSI.GetWrapPos (Var Line; LineSize: Byte; WrapPos: Byte) : Byte;
Var
Data : Array[1..255] of RecAnsiBufferChar absolute Line;
Begin
If GetLineLength(Line, LineSize) < WrapPos Then Begin
Result := 0;
Exit;
End;
Result := LineSize;
While (Result > 0) and ((Data[Result].Ch <> ' ') or (Result > WrapPos)) Do
Dec (Result);
End;
Function TEditorANSI.GetLineLength (Var Line; LineSize: Byte) : Byte;
Var
Data : Array[1..255] of RecAnsiBufferChar absolute Line;
Begin
Result := LineSize;
While (Result > 0) and (Data[Result].Ch = #0) Do
Dec (Result);
End;
2013-03-30 03:37:08 -07:00
Procedure TEditorANSI.WordWrap;
2013-03-04 07:53:06 -08:00
Var
WrapData : Array[1..255] of RecAnsiBufferChar;
TempStr : Array[1..255] of RecAnsiBufferChar;
NewLine : Array[1..255] of RecAnsiBufferChar;
Count : LongInt;
LineSize : Byte;
StartY : Byte;
StartLine : LongInt;
EndLine : LongInt;
First : Boolean = True;
Procedure Update;
Var
NewY : LongInt;
Begin
NewY := StartY + EndLine - StartLine + 1;
If NewY > WinSize Then NewY := WinSize;
If CurY > WinSize Then
2013-03-22 20:17:33 -07:00
ScrollDown(True)
2013-03-04 07:53:06 -08:00
Else
DrawPage (StartY, NewY, True);
End;
Begin
FillChar (WrapData, SizeOf(WrapData), #0);
Count := CurLine;
StartY := CurY;
StartLine := Count;
2013-05-09 01:38:41 -07:00
While Count <= MaxMsgLines Do Begin
2013-03-04 07:53:06 -08:00
If Count > LastLine Then LastLine := Count;
FillChar (TempStr, SizeOf(TempStr), #0);
Move (Ansi.Data[Count], TempStr, SizeOf(Ansi.Data[Count]));
If Not IsBlankLine(WrapData, 255) Then Begin
If IsBlankLine(TempStr, 255) Then Begin
If Count < LastLine Then Begin
InsertLine(Count);
2013-05-09 01:38:41 -07:00
EndLine := MaxMsgLines;
2013-03-04 07:53:06 -08:00
End Else
EndLine := Count;
Move (WrapData, ANSI.Data[Count], SizeOf(Ansi.Data[Count]));
Update;
Exit;
End;
FillChar (NewLine, SizeOf(NewLine), #0);
LineSize := GetLineLength(WrapData, 255);
Move (WrapData, NewLine, LineSize * SizeOf(RecAnsiBufferChar));
NewLine[LineSize + 1].Ch := ' ';
NewLine[LineSize + 1].Attr := WrapData[LineSize].Attr;
Move (TempStr, NewLine[LineSize + 2], GetLineLength(TempStr, 255) * SizeOf(RecAnsiBufferChar));
Move (NewLine, TempStr, SizeOf(NewLine));
End;
FillChar (WrapData, SizeOf(WrapData), #0);
LineSize := GetWrapPos(TempStr, 255, RowSize);
If LineSize > 0 Then Begin
Move (TempStr[LineSize], WrapData, (GetLineLength(TempStr, 255) - LineSize + 1) * SizeOf(RecAnsiBufferChar));
FillChar (TempStr[LineSize], (255 - LineSize) * SizeOf(RecAnsiBufferChar), #0);
2013-03-22 20:17:33 -07:00
TrimLeft (WrapData, 255);
2013-03-04 07:53:06 -08:00
If First Then Begin
If CurX > LineSize Then Begin
CurX := CurX - LineSize;
Inc (CurY);
Inc (CurLine);
End;
First := False;
End;
End;
FillChar (ANSI.Data[Count], SizeOf(ANSI.Data[Count]), #0);
Move (TempStr, ANSI.Data[Count], RowSize * SizeOf(RecAnsiBufferChar));
If LineSize = 0 Then Begin
2013-03-22 20:17:33 -07:00
EndLine := Count;
2013-03-04 07:53:06 -08:00
Update;
Exit;
End;
Inc (Count);
End;
End;
2013-03-22 20:17:33 -07:00
Procedure TEditorANSI.ToggleInsert (Toggle: Boolean);
2013-03-04 07:53:06 -08:00
Begin
2013-03-22 20:17:33 -07:00
If Toggle Then InsertMode := Not InsertMode;
2013-03-04 07:53:06 -08:00
2013-03-22 20:17:33 -07:00
Session.io.AnsiColor (Session.io.ScreenInfo[3].A);
Session.io.AnsiGotoXY (Session.io.ScreenInfo[3].X, Session.io.ScreenInfo[3].Y);
2013-03-04 07:53:06 -08:00
2013-08-30 21:38:55 -07:00
If InsertMode Then Session.io.BufAddStr('INS') Else Session.io.BufAddStr('OVR'); { ++lang++ }
2013-03-22 20:17:33 -07:00
End;
2013-03-04 07:53:06 -08:00
2013-03-22 20:17:33 -07:00
Procedure TEditorANSI.ReDrawTemplate (Reset: Boolean);
2013-03-24 02:47:36 -07:00
Var
Count : LongInt;
2013-03-22 20:17:33 -07:00
Begin
2013-05-20 02:35:04 -07:00
FillChar (Session.io.ScreenInfo, SizeOf(Session.io.ScreenInfo), 0);
2013-03-22 20:17:33 -07:00
TBBSCore(Owner).io.AllowArrow := True;
2013-03-04 07:53:06 -08:00
2013-08-30 21:38:55 -07:00
If DrawMode Then Begin
// temp until we show file
Session.io.ScreenInfo[1].Y := 3;
Session.io.ScreenInfo[2].Y := 24;
Session.io.AnsiColor(7);
Session.io.AnsiClear;
WriteXY (1, 1, 7, 'Draw Mode ESC/Menu - Insert: ' + Session.io.OutON(InsertMode) + ' GlyphMode: ' + Session.io.OutON(GlyphMode) + ' Set: ');
WriteXY (53, 1, CurAttr, GlyphTypeStr[GlyphPtr]);
WriteXY (1, 2, 8, strRep('-', 79));
End Else Begin
Session.io.PromptInfo[2] := Subject;
Session.io.OutFile (Template, True, 0);
2013-03-04 07:53:06 -08:00
2013-08-30 21:38:55 -07:00
ToggleInsert (False);
End;
2013-03-04 07:53:06 -08:00
2013-05-06 10:19:01 -07:00
WinX1 := 1;
2013-05-09 01:38:41 -07:00
WinX2 := MaxMsgCols; //79
2013-05-06 10:19:01 -07:00
// WinX1 := Session.io.ScreenInfo[1].X;
// WinX2 := Session.io.ScreenInfo[2].X;
2013-03-22 20:17:33 -07:00
WinY1 := Session.io.ScreenInfo[1].Y;
WinY2 := Session.io.ScreenInfo[2].Y;
2013-03-04 07:53:06 -08:00
WinSize := WinY2 - WinY1 + 1;
RowSize := WinX2 - WinX1 + 1;
2013-05-09 01:38:41 -07:00
// if rowsize > msgmaxcols then rowsize := maxmsgcols;
2013-03-04 07:53:06 -08:00
ClearEOL := RowSize >= 79;
2013-03-22 20:17:33 -07:00
If Reset Then Begin
2013-03-23 08:22:51 -07:00
CurX := 1;
CurY := 1;
CurAttr := Session.io.ScreenInfo[1].A;
QuoteAttr := Session.io.ScreenInfo[2].A;
2013-03-22 20:17:33 -07:00
FindLastLine;
2013-03-24 02:47:36 -07:00
If LastLine > 1 Then
For Count := 1 to LastLine Do
If Session.Msgs.IsQuotedText(GetLineText(Count)) Then
ANSI.SetLineColor(QuoteAttr, Count)
Else
ANSI.SetLineColor(CurAttr, Count);
2013-03-22 20:17:33 -07:00
End;
2013-03-04 07:53:06 -08:00
2013-03-30 03:37:08 -07:00
DrawPage (1, WinSize, False);
2013-03-04 07:53:06 -08:00
End;
Procedure TEditorANSI.LocateCursor;
Begin
CurLength := GetLineLength(ANSI.Data[CurLine], RowSize);
If CurX < 1 Then CurX := 1;
If CurX > CurLength Then CurX := CurLength + 1;
If CurY < 1 Then CurY := 1;
While TopLine + CurY - 1 > LastLine Do
Dec (CurY);
2013-03-30 03:37:08 -07:00
// With TBBSCore(Owner).io Do Begin
// AnsiGotoXY (1, 1);
// BufAddStr ('X:' + strI2S(CurX) + ' Y:' + strI2S(CurY) + ' CL:' + strI2S(CurLine) + ' TopL:' + strI2S(TopLine) + ' Last:' + strI2S(LastLine) + ' Len:' + strI2S(GetLineLength(ANSI.Data[CurLine], 80)) + ' Row:' + strI2S(RowSize) + ' ');
// End;
2013-03-04 07:53:06 -08:00
With TBBSCore(Owner).io Do Begin
AnsiGotoXY (WinX1 + CurX - 1, WinY1 + CurY - 1);
AnsiColor (CurAttr);
BufFlush;
End;
End;
Procedure TEditorANSI.DrawPage (StartY, EndY: Byte; ExitEOF: Boolean);
Var
CountY : LongInt;
Begin
For CountY := StartY to EndY Do Begin
If TopLine + CountY - 1 > LastLine + 1 Then Begin
TBBSCore(Owner).io.AnsiGotoXY (WinX1, WinY1 + CountY - 1);
TBBSCore(Owner).io.AnsiColor (7);
If ClearEOL Then
TBBSCore(Owner).io.AnsiClrEOL
Else
TBBSCore(Owner).io.BufAddStr (strRep(' ', RowSize));
End Else
If TopLine + CountY - 1 = LastLine + 1 Then Begin
TBBSCore(Owner).io.AnsiGotoXY (WinX1, WinY1 + CountY - 1);
2013-03-22 20:17:33 -07:00
TBBSCore(Owner).io.AnsiColor (8);
TBBSCore(Owner).io.BufAddStr (strPadC('(END)', RowSize, ' '));
2013-03-04 07:53:06 -08:00
2013-03-30 03:37:08 -07:00
If ExitEOF Then Exit;
2013-03-04 07:53:06 -08:00
End Else
DrawLine (TopLine + CountY - 1, 1, CountY);
End;
End;
Procedure TEditorANSI.ScrollUp;
Var
NewTop : LongInt;
Begin
NewTop := TopLine - (WinSize DIV 2) + 1;
If NewTop < 1 Then NewTop := 1;
CurY := CurLine - NewTop + 1;
TopLine := NewTop;
DrawPage(1, WinSize, False);
End;
2013-03-22 20:17:33 -07:00
Procedure TEditorANSI.ScrollDown (Draw: Boolean);
2013-03-04 07:53:06 -08:00
Var
NewTop : LongInt;
Begin
NewTop := TopLine + (WinSize DIV 2) + 1;
2013-05-09 01:38:41 -07:00
While NewTop >= MaxMsgLines Do
2013-03-04 07:53:06 -08:00
Dec (NewTop, 2);
CurY := CurLine - NewTop + 1;
TopLine := NewTop;
2013-03-22 20:17:33 -07:00
If Draw Then
DrawPage(1, WinSize, False);
2013-03-04 07:53:06 -08:00
End;
2013-03-31 22:08:13 -07:00
Function TEditorANSI.LineUp (Reset: Boolean) : Boolean;
2013-03-04 07:53:06 -08:00
Begin
Result := False;
If CurLine = 1 Then Exit;
Dec (CurLine);
Dec (CurY);
2013-03-31 22:08:13 -07:00
// might be able to use curlength
If Reset or (CurX > GetLineLength(ANSI.Data[CurLine], 80)) Then
CurX := GetLineLength(ANSI.Data[CurLine], 80) + 1;
2013-03-04 07:53:06 -08:00
If CurY < 1 Then Begin
ScrollUp;
Result := True;
End;
End;
Function TEditorANSI.LineDown (Reset: Boolean) : Boolean;
Begin
Result := False;
2013-03-31 22:08:13 -07:00
If CurLine >= LastLine Then Exit;
2013-05-09 01:38:41 -07:00
// If CurLine >= MaxMsgLines Then Exit;
2013-03-04 07:53:06 -08:00
Inc (CurLine);
Inc (CurY);
If Reset Then CurX := 1;
If CurX > GetLineLength(ANSI.Data[CurLine], 80) Then
CurX := GetLineLength(ANSI.Data[CurLine], 80) + 1;
2013-03-04 07:53:06 -08:00
If CurY > WinSize Then Begin
Result := True;
2013-03-22 20:17:33 -07:00
ScrollDown(True);
2013-03-04 07:53:06 -08:00
End;
End;
Procedure TEditorANSI.DrawLine (Line: LongInt; XP, YP: Byte);
Var
Count : Byte;
LineLen : Byte;
Begin
TBBSCore(Owner).io.AnsiGotoXY (WinX1 + XP - 1, WinY1 + YP - 1);
LineLen := GetLineLength(ANSI.Data[Line], RowSize);
For Count := XP to LineLen Do Begin
If ANSI.Data[Line][Count].Ch = #0 Then Begin
TBBSCore(Owner).io.AnsiColor (7);
TBBSCore(Owner).io.BufAddChar (' ');
End Else Begin
TBBSCore(Owner).io.AnsiColor (ANSI.Data[Line][Count].Attr);
TBBSCore(Owner).io.BufAddChar (ANSI.Data[Line][Count].Ch);
End;
End;
If LineLen < RowSize Then
If ClearEOL Then Begin
TBBSCore(Owner).io.AnsiColor (7);
TBBSCore(Owner).io.AnsiClrEOL;
End Else Begin
TBBSCore(Owner).io.AnsiColor (7);
2013-05-09 01:38:41 -07:00
TBBSCore(Owner).io.BufAddStr (strRep(' ', RowSize - LineLen));
2013-03-04 07:53:06 -08:00
End;
End;
Procedure TEditorANSI.DoDelete;
Var
JoinLen : Byte;
JoinPos : Byte;
JoinBuf : Array[1..255] of RecAnsiBufferChar;
Begin
If CurX <= CurLength Then Begin
2013-03-24 02:47:36 -07:00
Move (ANSI.Data[CurLine][CurX + 1], ANSI.Data[CurLine][CurX], (CurLength - CurX + 1) * SizeOf(RecAnsiBufferChar));
2013-03-04 07:53:06 -08:00
ANSI.Data[CurLine][CurLength].Ch := #0;
DrawLine (CurLine, CurX, CurY);
End Else
If CurLine < LastLine Then
If (CurLength = 0) and (LastLine > 1) Then Begin
DeleteLine (CurLine);
DrawPage (CurY, WinSize, False);
End Else Begin
JoinLen := GetLineLength(ANSI.Data[CurLine + 1], RowSize);
If CurLength + JoinLen <= RowSize Then Begin
Move (ANSI.Data[CurLine + 1], ANSI.Data[CurLine][CurX], SizeOf(RecAnsiBufferChar) * JoinLen);
DeleteLine (CurLine + 1);
DrawPage (CurY, WinSize, False); //optimize
End Else Begin
JoinPos := GetWrapPos(ANSI.Data[CurLine + 1], RowSize, RowSize - CurLength);
If JoinPos > 0 Then Begin
Move (ANSI.Data[CurLine + 1], ANSI.Data[CurLine][CurX], SizeOf(RecAnsiBufferChar) * (JoinPos - 1));
FillChar (JoinBuf, SizeOf(JoinBuf), #0);
Move (ANSI.Data[CurLine + 1][JoinPos + 1], JoinBuf, (JoinLen - JoinPos + 1) * SizeOf(RecAnsiBufferChar));
Move (JoinBuf, ANSI.Data[CurLine + 1], RowSize * SizeOf(RecAnsiBufferChar));
DrawPage (CurY, CurY + 1, True);
End;
End;
End;
End;
Procedure TEditorANSI.DoBackSpace;
Var
JoinPos : Byte;
JoinBuf : Array[1..255] of RecAnsiBufferChar;
Begin
If CurX > 1 Then Begin
Dec (CurX);
Move (ANSI.Data[CurLine][CurX + 1], ANSI.Data[CurLine][CurX], SizeOf(RecAnsiBufferChar) * (80 - CurX + 1));
ANSI.Data[CurLine][80].Ch := #0;
If CurX > GetLineLength(ANSI.Data[CurLine], 80) Then
TBBSCore(Owner).io.OutBS(1, True)
Else
DrawLine (CurLine, CurX, CurY);
End Else
If CurLine > 1 Then Begin
If GetLineLength(ANSI.Data[CurLine - 1], 80) + CurLength <= RowSize Then Begin
CurX := GetLineLength(ANSI.Data[CurLine - 1], 80) + 1;
Move (ANSI.Data[CurLine], ANSI.Data[CurLine - 1][CurX], SizeOf(RecAnsiBufferChar) * CurLength);
DeleteLine (CurLine);
2013-03-31 22:08:13 -07:00
If Not LineUp(False) Then DrawPage (CurY, WinSize, False); //optimize
2013-03-04 07:53:06 -08:00
End Else Begin
JoinPos := GetWrapPos(ANSI.Data[CurLine], RowSize, RowSize - GetLineLength(ANSI.Data[CurLine - 1], RowSize));
If JoinPos > 0 Then Begin
CurX := GetLineLength(ANSI.Data[CurLine - 1], 80) + 1;
Move (ANSI.Data[CurLine], ANSI.Data[CurLine - 1][CurX], SizeOf(RecAnsiBufferChar) * (JoinPos - 1));
FillChar (JoinBuf, SizeOf(JoinBuf), #0);
Move (ANSI.Data[CurLine][JoinPos + 1], JoinBuf, (CurLength - JoinPos + 1) * SizeOf(RecAnsiBufferChar));
Move (JoinBuf, ANSI.Data[CurLine], RowSize * SizeOf(RecAnsiBufferChar));
2013-03-31 22:08:13 -07:00
If Not LineUp(False) Then DrawPage (CurY, WinSize, False);
2013-03-04 07:53:06 -08:00
End Else Begin
2013-03-31 22:08:13 -07:00
LineUp(False);
2013-03-04 07:53:06 -08:00
CurX := CurLength + 1;
End;
End;
End;
End;
Procedure TEditorANSI.DoChar (Ch: Char);
2013-05-20 02:35:04 -07:00
Var
CharAttr : Byte;
2013-03-04 07:53:06 -08:00
Begin
2013-08-30 21:38:55 -07:00
CharAttr := CurAttr;
If DrawMode Then Begin
If (Ch in ['0'..'9']) And GlyphMode Then
Ch := GlyphTypeStr[GlyphPtr][strS2I(Ch) + 1]
End Else
If (Session.io.ScreenInfo[6].A <> 0) and (Pos(Ch, '0123456789') > 0) Then
CharAttr := Session.io.ScreenInfo[6].A
Else
If (Session.io.ScreenInfo[5].A <> 0) and (Pos(Ch, '.,!@#$%^&*()_+-=~`''"?;:<>\/[]{}|') > 0) Then
CharAttr := Session.io.ScreenInfo[5].A
Else
If (Session.io.ScreenInfo[4].A <> 0) and (Ch = UpCase(Ch)) Then
CharAttr := Session.io.ScreenInfo[4].A;
2013-05-20 02:35:04 -07:00
2013-03-04 07:53:06 -08:00
If InsertMode Then Begin
Move (ANSI.Data[CurLine][CurX], ANSI.Data[CurLine][CurX + 1], SizeOf(RecAnsiBufferChar) * (CurLength - CurX + 1));
ANSI.Data[CurLine][CurX].Ch := Ch;
2013-05-20 02:35:04 -07:00
ANSI.Data[CurLine][CurX].Attr := CharAttr;
2013-03-04 07:53:06 -08:00
If CurLength < RowSize {-1} Then Begin
If CurX <= CurLength Then
DrawLine (CurLine, CurX, CurY)
Else Begin
2013-05-20 02:35:04 -07:00
TBBSCore(Owner).io.AnsiColor (CharAttr);
2013-03-04 07:53:06 -08:00
TBBSCore(Owner).io.BufAddChar (Ch);
End;
Inc (CurX);
End Else Begin
Inc (CurX);
2013-03-30 03:37:08 -07:00
WordWrap;
2013-03-04 07:53:06 -08:00
End;
End Else
If CurX <= RowSize Then Begin
ANSI.Data[CurLine][CurX].Ch := Ch;
2013-05-20 02:35:04 -07:00
ANSI.Data[CurLine][CurX].Attr := CharAttr;
2013-03-04 07:53:06 -08:00
2013-05-20 02:35:04 -07:00
TBBSCore(Owner).io.AnsiColor (CharAttr);
2013-03-04 07:53:06 -08:00
TBBSCore(Owner).io.BufAddChar (Ch);
Inc (CurX);
End;
End;
Procedure TEditorANSI.PageUp;
Var
NewTop : LongInt;
Begin
If CurLine = 1 Then Exit;
If TopLine = 1 Then Begin
CurLine := 1;
CurY := 1;
CurX := 1;
Exit;
End;
Dec (CurLine, WinSize);
If CurLine < 1 Then Begin
CurLine := 1;
NewTop := 1;
End Else Begin
NewTop := TopLine - WinSize;
If NewTop < 1 Then NewTop := 1;
End;
CurY := CurLine - NewTop + 1;
TopLine := NewTop;
DrawPage (1, WinSize, False);
2013-03-04 07:53:06 -08:00
End;
Procedure TEditorANSI.PageDown;
Var
NewTop : LongInt;
Begin
If CurLine = LastLine Then Exit;
If (LastLine > TopLine) And (LastLine <= TopLine + WinSize - 1) Then Begin
CurLine := LastLine;
CurY := CurLine - TopLine + 1;
CurX := 1;
Exit;
End;
Inc (CurLine, WinSize);
If CurLine > LastLine Then CurLine := LastLine;
NewTop := TopLine + WinSize;
While NewTop >= LastLine - (WinSize DIV 2) Do
Dec (NewTop);
If NewTop < 1 Then NewTop := 1;
CurY := CurLine - NewTop + 1;
TopLine := NewTop;
DrawPage (1, WinSize, False);
2013-03-04 07:53:06 -08:00
End;
Procedure TEditorANSI.DoEnter;
Var
TempLine : RecAnsiBufferLine;
Begin
2013-05-09 01:38:41 -07:00
If InsertMode and IsBlankLine(ANSI.Data[MaxMsgLines], 80) Then Begin
2013-03-04 07:53:06 -08:00
If CurX > CurLength Then Begin
InsertLine (CurLine + 1);
If Not LineDown(True) Then DrawPage(CurY, WinSize, True);
End Else Begin
TempLine := ANSI.Data[CurLine];
InsertLine (CurLine + 1);
FillChar (ANSI.Data[CurLine][CurX], SizeOf(RecAnsiBufferChar) * (80 - CurX + 1), #0);
Move (TempLine[CurX], ANSI.Data[CurLine + 1][1], SizeOf(RecAnsiBufferChar) * (80 - CurX + 1));
If Not LineDown(True) Then
DrawPage (CurY - 1, WinSize, True);
End;
2013-08-30 21:38:55 -07:00
End Else Begin
If CurLine = LastLine Then
InsertLine (CurLine + 1);
If Not LineDown(True) Then
DrawPage (CurY - 1, WinSize, True);
End;
2013-03-04 07:53:06 -08:00
End;
2013-03-22 20:17:33 -07:00
Procedure TEditorANSI.Quote;
Var
InFile : Text;
Start : Integer;
Finish : Integer;
NumLines : Integer;
Text : Array[1..mysMaxMsgLines] of String[80];
PI1 : String;
PI2 : String;
Begin
Assign (InFile, Session.TempPath + 'msgtmp');
{$I-} Reset (InFile); {$I+}
If IoResult <> 0 Then Begin
Session.io.OutFullLn (Session.GetPrompt(158));
Exit;
End;
NumLines := 0;
2013-03-30 03:37:08 -07:00
2013-03-22 20:17:33 -07:00
Session.io.AllowPause := True;
While Not Eof(InFile) Do Begin
Inc (NumLines);
ReadLn (InFile, Text[NumLines]);
End;
Close (InFile);
PI1 := Session.io.PromptInfo[1];
PI2 := Session.io.PromptInfo[2];
Session.io.OutFullLn('|CL' + Session.GetPrompt(452));
For Start := 1 to NumLines Do Begin
Session.io.PromptInfo[1] := strI2S(Start);
Session.io.PromptInfo[2] := Text[Start];
Session.io.OutFullLn (Session.GetPrompt(341));
If (Session.io.PausePtr >= Session.User.ThisUser.ScreenSize) and (Session.io.AllowPause) Then
Case Session.io.MorePrompt of
'N' : Break;
'C' : Session.io.AllowPause := False;
End;
End;
Session.io.AllowPause := True;
Session.io.OutFull (Session.GetPrompt(159));
Start := strS2I(Session.io.GetInput(3, 3, 11, ''));
Session.io.OutFull (Session.GetPrompt(160));
Finish := strS2I(Session.io.GetInput(3, 3, 11, ''));
If (Start > 0) and (Start <= NumLines) and (Finish <= NumLines) Then Begin
If Finish = 0 Then Finish := Start;
For NumLines := Start to Finish Do Begin
2013-05-09 01:38:41 -07:00
If LastLine = MaxMsgLines Then Break;
2013-03-22 20:17:33 -07:00
If Not IsBlankLine(Ansi.Data[CurLine], 80) Then Begin
Inc (CurLine);
Inc (CurY);
InsertLine (CurLine);
End;
SetLineText (CurLine, Text[NumLines]);
2013-03-23 08:22:51 -07:00
ANSI.SetLineColor (QuoteAttr, CurLine);
2013-03-22 20:17:33 -07:00
If CurY > WinSize Then
ScrollDown(False);
End;
End;
2013-05-09 01:38:41 -07:00
If CurLine < MaxMsgLines Then Begin
2013-03-22 20:17:33 -07:00
Inc (CurLine);
Inc (CurY);
InsertLine(CurLine);
If CurY > WinSize Then
ScrollDown(False);
End;
Session.io.PromptInfo[1] := PI1;
Session.io.PromptInfo[2] := PI2;
End;
Procedure TEditorANSI.QuoteWindow;
Var
QText : Array[1..mysMaxMsgLines] of String[79];
2013-05-20 02:35:04 -07:00
QTextSize : Byte;
2013-03-22 20:17:33 -07:00
InFile : Text;
QuoteLines : Integer;
NoMore : Boolean;
Procedure UpdateBar (On: Boolean);
Begin
Session.io.AnsiGotoXY (1, QuoteCurLine + Session.io.ScreenInfo[2].Y);
If On Then
2013-05-20 02:35:04 -07:00
Session.io.AnsiColor (Session.io.ScreenInfo[3].A)
2013-03-22 20:17:33 -07:00
Else
Session.io.AnsiColor (Session.io.ScreenInfo[2].A);
Session.io.BufAddStr (strPadR(QText[QuoteTopPage + QuoteCurLine], 79, ' '));
End;
Procedure UpdateWindow;
Var
Count : Integer;
Begin
Session.io.AnsiGotoXY (1, Session.io.ScreenInfo[2].Y);
Session.io.AnsiColor (Session.io.ScreenInfo[2].A);
2013-05-20 02:35:04 -07:00
For Count := QuoteTopPage to QuoteTopPage + QTextSize - 1 Do Begin
2013-03-22 20:17:33 -07:00
If Count <= QuoteLines Then Session.io.BufAddStr (QText[Count]);
Session.io.AnsiClrEOL;
If Count <= QuoteLines Then Session.io.BufAddStr(#13#10);
End;
UpdateBar(True);
End;
Var
Ch : Char;
QWinSize : Byte;
QWinDataPos : Byte;
QWinData : Array[1..15] of String[79];
Procedure AddQuoteWin (S: String);
Var
Count : Byte;
Begin
If QWinDataPos < QWinSize Then Begin
Inc (QWinDataPos);
End Else Begin
For Count := 2 to QWinSize Do
QWinData[Count - 1] := QWinData[Count]
End;
QWinData[QWinDataPos] := S;
End;
Procedure DrawQWin;
Var
Count : Byte;
Begin
2013-05-20 02:35:04 -07:00
Session.io.AnsiColor (Session.io.ScreenInfo[1].A);
2013-03-22 20:17:33 -07:00
2013-03-23 08:22:51 -07:00
For Count := 1 to QWinSize + 1 Do Begin
2013-03-22 20:17:33 -07:00
Session.io.AnsiGotoXY (WinX1, WinY1 + Count - 1);
2013-03-23 08:22:51 -07:00
If Count <= QWinSize Then
Session.io.BufAddStr(QWinData[Count]);
2013-03-22 20:17:33 -07:00
Session.io.AnsiClrEOL;
End;
End;
2013-03-23 08:22:51 -07:00
Var
Temp : Integer;
2013-03-22 20:17:33 -07:00
Begin
Assign (InFile, Session.TempPath + 'msgtmp');
{$I-} Reset(InFile); {$I+}
If IoResult <> 0 Then Exit;
NoMore := False;
QWinDataPos := 0;
2013-03-23 08:22:51 -07:00
QuoteLines := 0;
2013-03-22 20:17:33 -07:00
While Not Eof(InFile) Do Begin
Inc (QuoteLines);
ReadLn (InFile, QText[QuoteLines]);
End;
Close (InFile);
Session.io.OutFile ('ansiquot', True, 0);
2013-03-23 08:22:51 -07:00
FillChar (QWinData, SizeOf(QWinData), 0);
2013-03-22 20:17:33 -07:00
2013-05-20 02:35:04 -07:00
QTextSize := Session.io.ScreenInfo[3].Y - Session.io.ScreenInfo[2].Y + 1;
QWinSize := Session.io.ScreenInfo[1].Y - WinY1 + 1;
2013-03-22 20:17:33 -07:00
2013-03-23 08:22:51 -07:00
For Temp := CurLine - ((QWinSize DIV 2) + 1) To CurLine - 1 Do
If Temp >= 1 Then AddQuoteWin(GetLineText(Temp));
2013-03-22 20:17:33 -07:00
DrawQWin;
UpdateWindow;
Repeat
Ch := Session.io.GetKey;
If Session.io.IsArrow Then Begin
Case Ch of
#71 : If QuoteCurLine > 0 Then Begin
QuoteTopPage := 1;
QuoteCurLine := 0;
2013-05-20 02:35:04 -07:00
NoMore := False;
2013-03-22 20:17:33 -07:00
UpdateWindow;
End;
#72 : Begin
If QuoteCurLine > 0 Then Begin
UpdateBar(False);
Dec(QuoteCurLine);
UpdateBar(True);
End Else
If QuoteTopPage > 1 Then Begin
Dec (QuoteTopPage);
UpdateWindow;
End;
NoMore := False;
End;
#73,
#75 : Begin
2013-05-20 02:35:04 -07:00
If QuoteTopPage > QTextSize Then
Dec (QuoteTopPage, QTextSize)
2013-03-22 20:17:33 -07:00
Else Begin
QuoteTopPage := 1;
QuoteCurLine := 0;
End;
NoMore := False;
UpdateWindow;
End;
#79 : Begin
2013-05-20 02:35:04 -07:00
If QuoteLines <= QTextSize Then
2013-03-22 20:17:33 -07:00
QuoteCurLine := QuoteLines - QuoteTopPage
Else Begin
2013-05-20 02:35:04 -07:00
QuoteTopPage := QuoteLines - QTextSize + 1;
QuoteCurLine := QTextSize - 1;
2013-03-22 20:17:33 -07:00
End;
UpdateWindow;
End;
#80 : If QuoteTopPage + QuoteCurLine < QuoteLines Then Begin
2013-05-20 02:35:04 -07:00
If QuoteCurLine = QTextSize - 1 Then Begin
2013-03-22 20:17:33 -07:00
Inc (QuoteTopPage);
UpdateWindow;
End Else Begin
UpdateBar(False);
Inc (QuoteCurLine);
UpdateBar(True);
End;
End;
#77,
#81 : Begin
2013-05-20 02:35:04 -07:00
If QuoteLines <= QTextSize Then
2013-03-22 20:17:33 -07:00
QuoteCurLine := QuoteLines - QuoteTopPage
Else
2013-05-20 02:35:04 -07:00
If QuoteTopPage + QTextSize - 1 < QuoteLines - QTextSize + 1 Then
Inc (QuoteTopPage, QTextSize)
2013-03-22 20:17:33 -07:00
Else Begin
2013-05-20 02:35:04 -07:00
QuoteTopPage := QuoteLines - QTextSize + 1;
QuoteCurLine := QTextSize - 1;
2013-03-22 20:17:33 -07:00
End;
UpdateWindow;
End;
End;
End Else
Case Ch of
#27 : Break;
2013-05-09 01:38:41 -07:00
#13 : If (LastLine < MaxMsgLines) and (Not NoMore) Then Begin
2013-03-22 20:17:33 -07:00
If QuoteTopPage + QuoteCurLine = QuoteLines Then NoMore := True;
InsertLine (CurLine);
SetLineText (CurLine, QText[QuoteTopPage + QuoteCurLine]);
2013-03-23 08:22:51 -07:00
ANSI.SetLineColor (QuoteAttr, CurLine);
2013-03-22 20:17:33 -07:00
Inc (CurLine);
Inc (CurY);
If CurY > WinSize Then
ScrollDown(False);
AddQuoteWin(QText[QuoteTopPage + QuoteCurLine]);
DrawQWin;
If QuoteTopPage + QuoteCurLine < QuoteLines Then
2013-05-20 02:35:04 -07:00
If QuoteCurLine = QTextSize - 1 Then Begin
2013-03-22 20:17:33 -07:00
Inc (QuoteTopPage);
UpdateWindow;
End Else Begin
UpdateBar(False);
Inc (QuoteCurLine);
UpdateBar(True);
End;
End;
End;
Until False;
Session.io.OutFull('|16');
2013-05-09 01:38:41 -07:00
If CurLine < MaxMsgLines Then Begin
2013-03-23 08:22:51 -07:00
Inc (CurLine);
Inc (CurY);
InsertLine(CurLine);
If CurY > WinSize Then
ScrollDown(False);
End;
2013-03-22 20:17:33 -07:00
End;
2013-08-30 21:38:55 -07:00
Procedure TEditorANSI.EditorCommands;
2013-03-22 20:17:33 -07:00
Var
Ch : Char;
Str : String;
Begin
Done := False;
Save := False;
Repeat
Session.io.OutFull (Session.GetPrompt(354));
2013-08-30 21:38:55 -07:00
{$IFDEF TESTEDITOR}
Ch := Session.io.OneKey ('?ACDHQRSTU', True);
{$ELSE}
2013-03-22 20:17:33 -07:00
Ch := Session.io.OneKey ('?ACHQRSTU', True);
2013-08-30 21:38:55 -07:00
{$ENDIF}
2013-03-22 20:17:33 -07:00
Case Ch of
'?' : Session.io.OutFullLn (Session.GetPrompt(355));
'A' : If Forced Then Begin
Session.io.OutFull (Session.GetPrompt(307));
Exit;
End Else Begin
Done := Session.io.GetYN(Session.GetPrompt(356), False);
2013-08-30 21:38:55 -07:00
2013-03-22 20:17:33 -07:00
Exit;
End;
'C' : Exit;
2013-08-30 21:38:55 -07:00
'D' : Begin
DrawMode := True;
SavedInsert := InsertMode;
InsertMode := False;
Exit;
End;
2013-03-22 20:17:33 -07:00
'H' : Begin
Session.io.OutFile ('fshelp', True, 0);
Exit;
End;
'Q' : Begin
If Session.User.ThisUser.UseLBQuote Then
QuoteWindow
Else
Quote;
Exit;
End;
'R' : Exit;
'S' : Begin
Save := True;
Done := True;
End;
'T' : Begin
Session.io.OutFull(Session.GetPrompt(463));
2013-04-01 13:22:22 -07:00
Str := Session.io.GetInput(60, 60, 11, Subject);
If Str <> '' Then Subject := Str;
Session.io.PromptInfo[2] := Subject;
2013-03-22 20:17:33 -07:00
Exit;
End;
'U' : Begin
MessageUpload;
Exit;
End;
End;
Until Done;
End;
2013-08-30 21:38:55 -07:00
Procedure TEditorANSI.DrawCommands;
Var
Ch : Char;
Begin
Repeat
Session.io.OutFull ('|CR|09Draw Commands (?/Help): ');
Ch := Session.io.OneKey ('?GQ', True);
Case Ch of
'?' : Session.io.OutFullLn ('|CR(Q)uit Draw Mode (G)lyph Mode');
'G' : Begin
GlyphMode := Not GlyphMode;
Exit;
End;
'Q' : Begin
DrawMode := False;
InsertMode := SavedInsert;
Exit;
End;
End;
Until False;
End;
2013-03-22 20:17:33 -07:00
Procedure TEditorANSI.MessageUpload;
Var
FN : String[100];
T1 : String[30];
T2 : String[60];
OK : Boolean;
F : File;
B : Array[1..2048] of Char;
BR : LongInt;
Begin
OK := False;
T1 := Session.io.PromptInfo[1];
T2 := Session.io.PromptInfo[2];
Session.io.OutFull (Session.GetPrompt(352));
If Session.LocalMode Then Begin
FN := Session.io.GetInput(70, 70, 11, '');
If FN = '' Then Exit;
OK := FileExist(FN);
End Else Begin
FN := Session.TempPath + Session.io.GetInput(70, 70, 11, '');
If Session.FileBase.SelectProtocol(True, False) = 'Q' Then Exit;
Session.FileBase.ExecuteProtocol(1, FN);
OK := Session.FileBase.dszSearch(JustFile(FN));
End;
If OK Then Begin
Assign (F, FN);
Reset (F, 1);
2013-04-01 13:22:22 -07:00
ANSI.Lines := CurLine;
Ansi.CurX := CurX;
Ansi.CurY := CurLine;
2013-03-22 20:17:33 -07:00
While Not Eof(F) Do Begin
BlockRead (F, B, SizeOf(B), BR);
If BR = 0 Then Break;
ANSI.ProcessBuf(B, BR);
End;
Close(F);
End;
If Not Session.LocalMode Then FileErase(FN);
DirClean (Session.TempPath, 'msgtmp');
Session.io.PromptInfo[1] := T1;
Session.io.PromptInfo[2] := T2;
FindLastLine;
End;
2013-03-30 03:37:08 -07:00
Procedure TEditorANSI.ReformParagraph;
Var
Line : LongInt;
LineLen : Byte;
JoinPos : Byte;
JoinLen : Byte;
JoinBuf : Array[1..255] of RecAnsiBufferChar;
Begin
Line := CurLine;
Repeat
If (Line = LastLine) or IsBlankLine(ANSI.Data[Line], RowSize) Then Break;
TrimRight (ANSI.Data[Line], RowSize);
TrimLeft (ANSI.Data[Line + 1], RowSize);
LineLen := GetLineLength(ANSI.Data[Line], RowSize);
JoinLen := GetLineLength(ANSI.Data[Line + 1], RowSize);
JoinPos := GetWrapPos(ANSI.Data[Line + 1], JoinLen, RowSize - LineLen);
If JoinLen = 0 Then Break;
If LineLen + JoinLen <= RowSize Then Begin
Move (ANSI.Data[Line + 1], ANSI.Data[Line][LineLen + 2], SizeOf(RecAnsiBufferChar) * JoinLen);
2013-03-31 22:08:13 -07:00
ANSI.Data[Line][LineLen + 1].Ch := ' ';
2013-03-30 03:37:08 -07:00
DeleteLine (Line + 1);
End Else
If JoinPos > 0 Then Begin
Move (ANSI.Data[Line + 1], ANSI.Data[Line][LineLen + 2], SizeOf(RecAnsiBufferChar) * (JoinPos - 1));
2013-03-31 22:08:13 -07:00
ANSI.Data[Line][LineLen + 1].Ch := ' ';
2013-03-30 03:37:08 -07:00
FillChar (JoinBuf, SizeOf(JoinBuf), #0);
Move (ANSI.Data[Line + 1][JoinPos + 1], JoinBuf, (JoinLen - JoinPos + 1) * SizeOf(RecAnsiBufferChar));
Move (JoinBuf, ANSI.Data[Line + 1], RowSize * SizeOf(RecAnsiBufferChar));
End Else
Inc (Line);
Until False;
DrawPage (CurY, WinSize, False);
// need to optimize this output.
End;
2013-03-04 07:53:06 -08:00
Function TEditorANSI.Edit : Boolean;
Var
2013-03-30 03:37:08 -07:00
Ch : Char;
Count : LongInt;
2013-03-04 07:53:06 -08:00
Begin
2013-03-22 20:17:33 -07:00
Result := False;
QuoteCurLine := 0;
QuoteTopPage := 1;
2013-03-04 07:53:06 -08:00
2013-03-22 20:17:33 -07:00
ReDrawTemplate(True);
2013-03-04 07:53:06 -08:00
2013-03-22 20:17:33 -07:00
Repeat
2013-03-04 07:53:06 -08:00
LocateCursor;
Ch := TBBSCore(Owner).io.GetKey;
If Session.io.IsArrow Then Begin
Case Ch of
#71 : CurX := 1;
2013-03-31 22:08:13 -07:00
#72 : LineUp(False);
2013-03-22 20:17:33 -07:00
#73 : PageUp;
2013-03-31 22:08:13 -07:00
#75 : If CurX > 1 Then Dec(CurX) Else LineUp(True);
#77 : If CurX <= CurLength Then Inc(CurX) Else LineDown(True);
2013-03-22 20:17:33 -07:00
#79 : CurX := CurLength + 1;
#80 : If CurLine < LastLine Then LineDown(False);
2013-03-04 07:53:06 -08:00
#81 : PageDown;
2013-03-13 20:56:42 -07:00
#83 : DoDelete;
2013-03-04 07:53:06 -08:00
End;
End Else
Case Ch of
2013-03-30 03:37:08 -07:00
^B : ReformParagraph;
2013-03-31 22:08:13 -07:00
^F : CurX := 1;
^G : CurX := CurLength + 1;
^H : DoBackSpace;
2013-08-30 21:38:55 -07:00
^I : If CurLength < RowSize Then Begin
2013-03-31 22:08:13 -07:00
If (CurX < RowSize) and (CurX MOD 5 = 0) Then
DoChar(' ');
While (CurX < RowSize) and (CurX MOD 5 <> 0) Do Begin
CurLength := GetLineLength(ANSI.Data[CurLine], RowSize);
DoChar(' ');
End;
End;
2013-03-30 03:37:08 -07:00
^K : Begin
If CutPasted Then Begin
CutTextPos := 0;
CutPasted := False;
End;
If CutTextPos < fseMaxCutText Then Begin
Inc (CutTextPos);
CutText[CutTextPos] := ANSI.Data[CurLine];
DeleteLine(CurLine);
DrawPage (CurY, WinSize, False); //optimize + 1
End;
End;
2013-03-31 22:08:13 -07:00
^M : DoEnter;
2013-03-30 03:37:08 -07:00
^O : Begin
Session.io.OutFile('fshelp', True, 0);
ReDrawTemplate(False);
End;
2013-08-30 21:38:55 -07:00
^Q : If Not DrawMode Then Begin
2013-03-22 20:17:33 -07:00
If Session.User.ThisUser.UseLBQuote Then
QuoteWindow
Else
Quote;
ReDrawTemplate(False);
End;
2013-03-30 03:37:08 -07:00
^U : If CutTextPos > 0 Then Begin
CutPasted := True;
For Count := CutTextPos DownTo 1 Do
2013-05-09 01:38:41 -07:00
If LastLine < MaxMsgLines Then Begin
2013-03-30 03:37:08 -07:00
InsertLine(CurLine);
ANSI.Data[CurLine] := CutText[Count];
End;
DrawPage (CurY, WinSize, False);
End;
2013-03-22 20:17:33 -07:00
^V : ToggleInsert(True);
^Y : If (CurLine < LastLine) or ((CurLine = LastLine) And Not IsBlankLine(ANSI.Data[CurLine], 80)) Then Begin
2013-03-04 07:53:06 -08:00
DeleteLine (CurLine);
If CurLine > LastLine Then
InsertLine (CurLine);
DrawPage (CurY, WinSize, False);
End;
2013-03-22 20:17:33 -07:00
^Z,
^[ : Begin
2013-08-30 21:38:55 -07:00
If DrawMode Then
DrawCommands
Else
EditorCommands;
2013-03-22 20:17:33 -07:00
If (Not Save) and (Not Done) Then ReDrawTemplate(False);
End;
2013-03-04 07:53:06 -08:00
#32..
2013-08-30 21:38:55 -07:00
#254 : If (CurLength >= RowSize) and (GetWrapPos(ANSI.Data[CurLine], RowSize, RowSize) = 0) And InsertMode Then Begin
2013-03-22 20:17:33 -07:00
// dont do anything
End Else
2013-08-30 21:38:55 -07:00
If (CurX = 1) and (Ch = '/') and (Not DrawMode) Then Begin
EditorCommands;
2013-03-22 20:17:33 -07:00
2013-08-30 21:38:55 -07:00
If (Not Save) and (Not Done) Then ReDrawTemplate(False);
End Else
DoChar(Ch);
2013-03-04 07:53:06 -08:00
End;
2013-03-22 20:17:33 -07:00
Until Done;
Session.io.AllowArrow := False;
If Save Then FindLastLine;
Result := Save;
2013-03-07 07:39:10 -08:00
2013-03-22 20:17:33 -07:00
Session.io.AnsiGotoXY (1, Session.User.ThisUser.ScreenSize);
2013-03-04 07:53:06 -08:00
End;
End.