mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 08:08:45 +02:00
4668 lines
124 KiB
ObjectPascal
4668 lines
124 KiB
ObjectPascal
{
|
||
This file is part of the Free Pascal Integrated Development Environment
|
||
Copyright (c) 1998 by Berczi Gabor
|
||
|
||
Views and view-related functions for the IDE
|
||
|
||
See the file COPYING.FPC, included in this distribution,
|
||
for details about the copyright.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
||
**********************************************************************}
|
||
unit FPViews;
|
||
|
||
{$i globdir.inc}
|
||
|
||
interface
|
||
|
||
uses
|
||
Dos,Objects,Drivers,
|
||
FVConsts,
|
||
Views,Menus,Dialogs,App,Gadgets,Tabs,
|
||
ASCIITAB,
|
||
WEditor,WCEdit,
|
||
WUtils,WHelp,WHlpView,WViews,WANSI,
|
||
Comphook,
|
||
FPConst,FPUsrScr;
|
||
|
||
type
|
||
TEditor = TCodeEditor;
|
||
PEditor = PCodeEditor;
|
||
|
||
PStoreCollection = ^TStoreCollection;
|
||
TStoreCollection = object(TStringCollection)
|
||
function Add(const S: string): PString;
|
||
end;
|
||
|
||
PIntegerLine = ^TIntegerLine;
|
||
TIntegerLine = object(TInputLine)
|
||
constructor Init(var Bounds: TRect; AMin, AMax: longint);
|
||
end;
|
||
|
||
PFPHeapView = ^TFPHeapView;
|
||
TFPHeapView = object(THeapView)
|
||
constructor Init(var Bounds: TRect);
|
||
constructor InitKb(var Bounds: TRect);
|
||
procedure HandleEvent(var Event: TEvent); virtual;
|
||
end;
|
||
|
||
PFPClockView = ^TFPClockView;
|
||
TFPClockView = object(TClockView)
|
||
constructor Init(var Bounds: TRect);
|
||
procedure HandleEvent(var Event: TEvent); virtual;
|
||
function GetPalette: PPalette; virtual;
|
||
end;
|
||
|
||
PFPWindow = ^TFPWindow;
|
||
TFPWindow = object(TWindow)
|
||
AutoNumber: boolean;
|
||
procedure HandleEvent(var Event: TEvent); virtual;
|
||
procedure SetState(AState: Word; Enable: Boolean); virtual;
|
||
procedure UpdateCommands; virtual;
|
||
constructor Load(var S: TStream);
|
||
procedure Store(var S: TStream);
|
||
procedure Update; virtual;
|
||
procedure SelectInDebugSession;
|
||
end;
|
||
|
||
PFPHelpViewer = ^TFPHelpViewer;
|
||
TFPHelpViewer = object(THelpViewer)
|
||
function GetLocalMenu: PMenu; virtual;
|
||
function GetCommandTarget: PView; virtual;
|
||
end;
|
||
|
||
PFPHelpWindow = ^TFPHelpWindow;
|
||
TFPHelpWindow = object(THelpWindow)
|
||
constructor Init(var Bounds: TRect; ATitle: TTitleStr; ASourceFileID: word; AContext: THelpCtx; ANumber: Integer);
|
||
destructor Done;virtual;
|
||
procedure InitHelpView; virtual;
|
||
procedure Show; {virtual;}
|
||
procedure Hide; {virtual;}
|
||
procedure HandleEvent(var Event: TEvent); virtual;
|
||
function GetPalette: PPalette; virtual;
|
||
constructor Load(var S: TStream);
|
||
procedure Store(var S: TStream);
|
||
end;
|
||
|
||
PTextScroller = ^TTextScroller;
|
||
TTextScroller = object(TStaticText)
|
||
TopLine: integer;
|
||
Speed : integer;
|
||
Lines : PUnsortedStringCollection;
|
||
constructor Init(var Bounds: TRect; ASpeed: integer; AText: PUnsortedStringCollection);
|
||
function GetLineCount: integer; virtual;
|
||
function GetLine(I: integer): string; virtual;
|
||
procedure HandleEvent(var Event: TEvent); virtual;
|
||
procedure Update; virtual;
|
||
procedure Reset; virtual;
|
||
procedure Scroll; virtual;
|
||
procedure Draw; virtual;
|
||
destructor Done; virtual;
|
||
private
|
||
LastTT: longint;
|
||
end;
|
||
|
||
TAlign = (alLeft,alCenter,alRight);
|
||
|
||
PFPToolTip = ^TFPToolTip;
|
||
TFPToolTip = object(TView)
|
||
constructor Init(var Bounds: TRect; const AText: string; AAlign: TAlign);
|
||
procedure Draw; virtual;
|
||
function GetText: string;
|
||
procedure SetText(const AText: string);
|
||
function GetAlign: TAlign;
|
||
procedure SetAlign(AAlign: TAlign);
|
||
function GetPalette: PPalette; virtual;
|
||
destructor Done; virtual;
|
||
private
|
||
Text: PString;
|
||
Align: TAlign;
|
||
end;
|
||
|
||
PSourceEditor = ^TSourceEditor;
|
||
TSourceEditor = object(TFileEditor)
|
||
CompileStamp : longint;
|
||
CodeCompleteTip: PFPToolTip;
|
||
constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
|
||
PScrollBar; AIndicator: PIndicator;const AFileName: string);
|
||
{$ifndef NODEBUG}
|
||
private
|
||
ShouldHandleBreakpoints : boolean;
|
||
{$endif NODEBUG}
|
||
public
|
||
{ Syntax highlight }
|
||
function IsReservedWord(const S: string): boolean; virtual;
|
||
function IsAsmReservedWord(const S: string): boolean; virtual;
|
||
function GetSpecSymbolCount(SpecClass: TSpecSymbolClass): integer; virtual;
|
||
function GetSpecSymbol(SpecClass: TSpecSymbolClass; Index: integer): pstring; virtual;
|
||
{ CodeTemplates }
|
||
function TranslateCodeTemplate(var Shortcut: string; ALines: PUnsortedStringCollection): boolean; virtual;
|
||
function SelectCodeTemplate(var ShortCut: string): boolean; virtual;
|
||
{ CodeComplete }
|
||
function CompleteCodeWord(const WordS: string; var Text: string): boolean; virtual;
|
||
procedure FindMatchingDelimiter(ScanForward: boolean); virtual;
|
||
procedure SetCodeCompleteWord(const S: string); virtual;
|
||
procedure AlignCodeCompleteTip;
|
||
procedure HandleEvent(var Event: TEvent); virtual;
|
||
{$ifdef DebugUndo}
|
||
procedure DumpUndo;
|
||
procedure UndoAll;
|
||
procedure RedoAll;
|
||
{$endif DebugUndo}
|
||
function Valid(Command: Word): Boolean;virtual;
|
||
function GetLocalMenu: PMenu; virtual;
|
||
function GetCommandTarget: PView; virtual;
|
||
function CreateLocalMenuView(var Bounds: TRect; M: PMenu): PMenuPopup; virtual;
|
||
procedure ModifiedChanged; virtual;
|
||
procedure InsertOptions; virtual;
|
||
procedure PushInfo(Const st : string);virtual;
|
||
procedure PopInfo;virtual;
|
||
procedure DeleteLine(I: sw_integer); virtual;
|
||
procedure BackSpace; virtual;
|
||
procedure DelChar; virtual;
|
||
procedure DelSelect; virtual;
|
||
function InsertNewLine : Sw_integer;virtual;
|
||
function InsertLine(LineNo: sw_integer; const S: string): PCustomLine; virtual;
|
||
procedure AddLine(const S: string); virtual;
|
||
end;
|
||
|
||
PSourceWindow = ^TSourceWindow;
|
||
TSourceWindow = object(TFPWindow)
|
||
Editor : PSourceEditor;
|
||
Indicator : PIndicator;
|
||
NoNameCount : longint;
|
||
constructor Init(var Bounds: TRect; AFileName: string);
|
||
function GetTitle(MaxSize: sw_Integer): TTitleStr; virtual;
|
||
procedure SetTitle(ATitle: string); virtual;
|
||
procedure UpdateTitle; virtual;
|
||
procedure HandleEvent(var Event: TEvent); virtual;
|
||
procedure Update; virtual;
|
||
procedure UpdateCommands; virtual;
|
||
function GetPalette: PPalette; virtual;
|
||
constructor Load(var S: TStream);
|
||
procedure Store(var S: TStream);
|
||
procedure Close; virtual;
|
||
destructor Done; virtual;
|
||
end;
|
||
|
||
{$ifndef NODEBUG}
|
||
PGDBSourceEditor = ^TGDBSourceEditor;
|
||
TGDBSourceEditor = object(TSourceEditor)
|
||
function InsertNewLine : Sw_integer;virtual;
|
||
function Valid(Command: Word): Boolean; virtual;
|
||
procedure AddLine(const S: string); virtual;
|
||
procedure AddErrorLine(const S: string); virtual;
|
||
{ Syntax highlight }
|
||
function IsReservedWord(const S: string): boolean; virtual;
|
||
private
|
||
Silent,
|
||
AutoRepeat,
|
||
IgnoreStringAtEnd : boolean;
|
||
LastCommand : String;
|
||
end;
|
||
|
||
PGDBWindow = ^TGDBWindow;
|
||
TGDBWindow = object(TFPWindow)
|
||
Editor : PGDBSourceEditor;
|
||
Indicator : PIndicator;
|
||
constructor Init(var Bounds: TRect);
|
||
procedure HandleEvent(var Event: TEvent); virtual;
|
||
procedure WriteText(Buf : pchar;IsError : boolean);
|
||
procedure WriteString(Const S : string);
|
||
procedure WriteErrorString(Const S : string);
|
||
procedure WriteOutputText(Buf : pchar);
|
||
procedure WriteErrorText(Buf : pchar);
|
||
function GetPalette: PPalette;virtual;
|
||
constructor Load(var S: TStream);
|
||
procedure Store(var S: TStream);
|
||
procedure UpdateCommands; virtual;
|
||
destructor Done; virtual;
|
||
end;
|
||
|
||
PDisasLine = ^TDisasLine;
|
||
TDisasLine = object(TLine)
|
||
address : cardinal;{ should be target size of address for cross debuggers }
|
||
end;
|
||
|
||
PDisasLineCollection = ^TDisasLineCollection;
|
||
TDisasLineCollection = object(TLineCollection)
|
||
function At(Index: sw_Integer): PDisasLine;
|
||
end;
|
||
|
||
PDisassemblyEditor = ^TDisassemblyEditor;
|
||
TDisassemblyEditor = object(TSourceEditor)
|
||
CurrentSource : String;
|
||
CurrentLine : longint;
|
||
constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
|
||
PScrollBar; AIndicator: PIndicator;const AFileName: string);
|
||
procedure ReleaseSource;
|
||
destructor Done;virtual;
|
||
procedure AddSourceLine(const AFileName: string;line : longint); virtual;
|
||
procedure AddAssemblyLine(const S: string;AAddress : cardinal); virtual;
|
||
function GetCurrentLine(address : cardinal) : PDisasLine;
|
||
private
|
||
Source : PSourceWindow;
|
||
OwnsSource : Boolean;
|
||
DisasLines : PDisasLineCollection;
|
||
MinAddress,MaxAddress : cardinal;
|
||
CurL : PDisasLine;
|
||
end;
|
||
|
||
PDisassemblyWindow = ^TDisassemblyWindow;
|
||
TDisassemblyWindow = object(TFPWindow)
|
||
Editor : PDisassemblyEditor;
|
||
Indicator : PIndicator;
|
||
constructor Init(var Bounds: TRect);
|
||
procedure LoadFunction(Const FuncName : string);
|
||
procedure LoadAddress(Addr : cardinal);
|
||
function ProcessPChar(p : pchar) : boolean;
|
||
procedure HandleEvent(var Event: TEvent); virtual;
|
||
procedure WriteSourceString(Const S : string;line : longint);
|
||
procedure WriteDisassemblyString(Const S : string;address : cardinal);
|
||
procedure SetCurAddress(address : cardinal);
|
||
procedure UpdateCommands; virtual;
|
||
function GetPalette: PPalette;virtual;
|
||
destructor Done; virtual;
|
||
end;
|
||
{$endif NODEBUG}
|
||
|
||
PClipboardWindow = ^TClipboardWindow;
|
||
TClipboardWindow = object(TSourceWindow)
|
||
constructor Init;
|
||
procedure Close; virtual;
|
||
constructor Load(var S: TStream);
|
||
procedure Store(var S: TStream);
|
||
destructor Done; virtual;
|
||
end;
|
||
|
||
PMessageItem = ^TMessageItem;
|
||
TMessageItem = object(TObject)
|
||
TClass : longint;
|
||
Text : PString;
|
||
Module : PString;
|
||
Row,Col : sw_integer;
|
||
constructor Init(AClass: longint; const AText: string; AModule: PString; ARow, ACol: sw_integer);
|
||
function GetText(MaxLen: Sw_integer): string; virtual;
|
||
procedure Selected; virtual;
|
||
function GetModuleName: string; virtual;
|
||
destructor Done; virtual;
|
||
end;
|
||
|
||
PMessageListBox = ^TMessageListBox;
|
||
TMessageListBox = object(THSListBox)
|
||
Transparent : boolean;
|
||
NoSelection : boolean;
|
||
MaxWidth : Sw_integer;
|
||
ModuleNames : PStoreCollection;
|
||
constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
|
||
procedure SetState(AState: Word; Enable: Boolean); virtual;
|
||
procedure AddItem(P: PMessageItem); virtual;
|
||
function AddModuleName(const Name: string): PString; virtual;
|
||
function GetText(Item,MaxLen: Sw_Integer): String; virtual;
|
||
procedure Clear; virtual;
|
||
procedure TrackSource; virtual;
|
||
procedure GotoSource; virtual;
|
||
procedure Draw; virtual;
|
||
procedure HandleEvent(var Event: TEvent); virtual;
|
||
function GetLocalMenu: PMenu; virtual;
|
||
constructor Load(var S: TStream);
|
||
procedure Store(var S: TStream);
|
||
destructor Done; virtual;
|
||
end;
|
||
|
||
|
||
PFPDlgWindow = ^TFPDlgWindow;
|
||
TFPDlgWindow = object(TDlgWindow)
|
||
procedure HandleEvent(var Event: TEvent); virtual;
|
||
end;
|
||
|
||
(*
|
||
PTabItem = ^TTabItem;
|
||
TTabItem = record
|
||
Next : PTabItem;
|
||
View : PView;
|
||
Dis : boolean;
|
||
end;
|
||
|
||
PTabDef = ^TTabDef;
|
||
TTabDef = record
|
||
Next : PTabDef;
|
||
Name : PString;
|
||
Items : PTabItem;
|
||
DefItem : PView;
|
||
ShortCut : char;
|
||
end;
|
||
|
||
PTab = ^TTab;
|
||
TTab = object(TGroup)
|
||
TabDefs : PTabDef;
|
||
ActiveDef : integer;
|
||
DefCount : word;
|
||
constructor Init(var Bounds: TRect; ATabDef: PTabDef);
|
||
function AtTab(Index: integer): PTabDef; virtual;
|
||
procedure SelectTab(Index: integer); virtual;
|
||
function TabCount: integer;
|
||
procedure SelectNextTab(Forwards: boolean);
|
||
function Valid(Command: Word): Boolean; virtual;
|
||
procedure ChangeBounds(var Bounds: TRect); virtual;
|
||
procedure HandleEvent(var Event: TEvent); virtual;
|
||
function GetPalette: PPalette; virtual;
|
||
procedure Draw; virtual;
|
||
procedure SetState(AState: Word; Enable: Boolean); virtual;
|
||
destructor Done; virtual;
|
||
private
|
||
InDraw: boolean;
|
||
end;
|
||
*)
|
||
|
||
PScreenView = ^TScreenView;
|
||
TScreenView = object(TScroller)
|
||
Screen: PScreen;
|
||
constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar;
|
||
AScreen: PScreen);
|
||
procedure Draw; virtual;
|
||
procedure Update; virtual;
|
||
procedure HandleEvent(var Event: TEvent); virtual;
|
||
end;
|
||
|
||
PScreenWindow = ^TScreenWindow;
|
||
TScreenWindow = object(TFPWindow)
|
||
ScreenView : PScreenView;
|
||
constructor Init(AScreen: PScreen; ANumber: integer);
|
||
destructor Done; virtual;
|
||
end;
|
||
|
||
PFPAboutDialog = ^TFPAboutDialog;
|
||
TFPAboutDialog = object(TCenterDialog)
|
||
constructor Init;
|
||
procedure ToggleInfo;
|
||
procedure HandleEvent(var Event: TEvent); virtual;
|
||
private
|
||
Scroller: PTextScroller;
|
||
TitleST : PStaticText;
|
||
end;
|
||
|
||
PFPASCIIChart = ^TFPASCIIChart;
|
||
TFPASCIIChart = object(TASCIIChart)
|
||
constructor Init;
|
||
constructor Load(var S: TStream);
|
||
procedure Store(var S: TStream);
|
||
procedure HandleEvent(var Event: TEvent); virtual;
|
||
destructor Done; virtual;
|
||
end;
|
||
|
||
PVideoModeListBox = ^TVideoModeListBox;
|
||
TVideoModeListBox = object(TDropDownListBox)
|
||
function GetText(Item: pointer; MaxLen: sw_integer): string; virtual;
|
||
end;
|
||
|
||
PFPDesktop = ^TFPDesktop;
|
||
TFPDesktop = object(TDesktop)
|
||
constructor Init(var Bounds: TRect);
|
||
procedure InitBackground; virtual;
|
||
constructor Load(var S: TStream);
|
||
procedure Store(var S: TStream);
|
||
end;
|
||
|
||
PFPMemo = ^TFPMemo;
|
||
TFPMemo = object(TCodeEditor)
|
||
constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
|
||
PScrollBar; AIndicator: PIndicator);
|
||
function IsReservedWord(const S: string): boolean; virtual;
|
||
function GetSpecSymbolCount(SpecClass: TSpecSymbolClass): integer; virtual;
|
||
function GetSpecSymbol(SpecClass: TSpecSymbolClass; Index: integer): pstring; virtual;
|
||
function GetPalette: PPalette; virtual;
|
||
procedure HandleEvent(var Event: TEvent); virtual;
|
||
end;
|
||
|
||
PFPCodeMemo = ^TFPCodeMemo;
|
||
TFPCodeMemo = object(TFPMemo)
|
||
constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
|
||
PScrollBar; AIndicator: PIndicator);
|
||
function IsReservedWord(const S: string): boolean; virtual;
|
||
function GetSpecSymbolCount(SpecClass: TSpecSymbolClass): integer; virtual;
|
||
function GetSpecSymbol(SpecClass: TSpecSymbolClass; Index: integer): pstring; virtual;
|
||
end;
|
||
|
||
function SearchFreeWindowNo: integer;
|
||
|
||
function IsWindow(P: PView): boolean;
|
||
function IsThereAnyEditor: boolean;
|
||
function IsThereAnyWindow: boolean;
|
||
function IsThereAnyVisibleWindow: boolean;
|
||
function IsThereAnyNumberedWindow: boolean;
|
||
function FirstEditorWindow: PSourceWindow;
|
||
function EditorWindowFile(const Name : String): PSourceWindow;
|
||
procedure AskToReloadAllModifiedFiles;
|
||
|
||
{$ifndef NODEBUG}
|
||
function InDisassemblyWindow :boolean;
|
||
{$endif NODEBUG}
|
||
|
||
function NewTabItem(AView: PView; ANext: PTabItem): PTabItem;
|
||
procedure DisposeTabItem(P: PTabItem);
|
||
function NewTabDef(AName: string; ADefItem: PView; AItems: PTabItem; ANext: PTabDef): PTabDef;
|
||
procedure DisposeTabDef(P: PTabDef);
|
||
|
||
function GetEditorCurWord(Editor: PEditor; ValidSpecChars: TCharSet): string;
|
||
procedure InitReservedWords;
|
||
procedure DoneReservedWords;
|
||
function GetReservedWordCount: integer;
|
||
function GetReservedWord(Index: integer): string;
|
||
function GetAsmReservedWordCount: integer;
|
||
function GetAsmReservedWord(Index: integer): string;
|
||
|
||
procedure TranslateMouseClick(View: PView; var Event: TEvent);
|
||
|
||
function GetNextEditorBounds(var Bounds: TRect): boolean;
|
||
function OpenEditorWindow(Bounds: PRect; FileName: string; CurX,CurY: sw_integer): PSourceWindow;
|
||
function IOpenEditorWindow(Bounds: PRect; FileName: string; CurX,CurY: sw_integer; ShowIt: boolean): PSourceWindow;
|
||
function LastSourceEditor : PSourceWindow;
|
||
function SearchOnDesktop(FileName : string;tryexts:boolean) : PSourceWindow;
|
||
function TryToOpenFile(Bounds: PRect; FileName: string; CurX,CurY: sw_integer;tryexts: boolean): PSourceWindow;
|
||
function TryToOpenFileMulti(Bounds: PRect; FileName: string; CurX,CurY: sw_integer;tryexts: boolean): PSourceWindow;
|
||
function ITryToOpenFile(Bounds: PRect; FileName: string; CurX,CurY: sw_integer;tryexts, ShowIt,
|
||
ForceNewWindow:boolean): PSourceWindow;
|
||
function LocateSourceFile(const FileName: string; tryexts: boolean): string;
|
||
|
||
function SearchWindow(const Title: string): PWindow;
|
||
|
||
function StartEditor(Editor: PCodeEditor; FileName: string): boolean;
|
||
|
||
{$ifdef VESA}
|
||
procedure InitVESAScreenModes;
|
||
procedure DoneVESAScreenModes;
|
||
{$endif}
|
||
|
||
procedure NoDebugger;
|
||
|
||
const
|
||
SourceCmds : TCommandSet =
|
||
([cmSave,cmSaveAs,cmCompile,cmHide,cmDoReload]);
|
||
EditorCmds : TCommandSet =
|
||
([cmPrint,cmFind,cmReplace,cmSearchAgain,cmJumpLine,cmHelpTopicSearch,cmSelectAll,cmUnselect]);
|
||
CompileCmds : TCommandSet =
|
||
([cmMake,cmBuild,cmRun]);
|
||
|
||
CalcClipboard : extended = 0;
|
||
|
||
OpenFileName : string = '';
|
||
OpenFileLastExt : string[12] = '*.pas';
|
||
NewEditorOpened : boolean = false;
|
||
|
||
var MsgParms : array[1..10] of
|
||
record
|
||
case byte of
|
||
0 : (Ptr : pointer);
|
||
1 : (Long: longint);
|
||
end;
|
||
|
||
const menu_key_common_copy_borland = 'Ctrl+Ins';
|
||
menu_key_common_copy_microsoft = 'Ctrl+C';
|
||
|
||
menu_key_edit_undo = 'Alt+BkSp';
|
||
menu_key_edit_cut_borland = 'Shift+Del';
|
||
menu_key_edit_copy_borland = menu_key_common_copy_borland;
|
||
menu_key_edit_paste_borland = 'Shift+Ins';
|
||
menu_key_edit_cut_microsoft = 'Ctrl+X';
|
||
menu_key_edit_copy_microsoft = menu_key_common_copy_microsoft;
|
||
menu_key_edit_paste_microsoft = 'Ctrl+V';
|
||
menu_key_edit_clear = 'Ctrl+Del';
|
||
|
||
menu_key_common_helpindex = 'Shift+F1';
|
||
menu_key_common_topicsearch = 'Ctrl+F1';
|
||
menu_key_common_prevtopic = 'Alt+F1';
|
||
|
||
menu_key_help_helpindex= menu_key_common_helpindex;
|
||
menu_key_help_topicsearch = menu_key_common_topicsearch;
|
||
menu_key_help_prevtopic= menu_key_common_prevtopic;
|
||
|
||
menu_key_hlplocal_index = menu_key_common_helpindex;
|
||
menu_key_hlplocal_topicsearch = menu_key_common_topicsearch;
|
||
menu_key_hlplocal_prevtopic = menu_key_common_prevtopic;
|
||
menu_key_hlplocal_copy_borland = menu_key_common_copy_borland;
|
||
menu_key_hlplocal_copy_microsoft = menu_key_common_copy_microsoft;
|
||
|
||
{Configurable keys.}
|
||
const menu_key_edit_cut:string[63]=menu_key_edit_cut_borland;
|
||
menu_key_edit_copy:string[63]=menu_key_edit_copy_borland;
|
||
menu_key_edit_paste:string[63]=menu_key_edit_paste_borland;
|
||
menu_key_hlplocal_copy:string[63]=menu_key_hlplocal_copy_borland;
|
||
cut_key:word=kbShiftDel;
|
||
copy_key:word=kbCtrlIns;
|
||
paste_key:word=kbShiftIns;
|
||
|
||
procedure RegisterFPViews;
|
||
|
||
implementation
|
||
|
||
uses
|
||
Video,Strings,Keyboard,Validate,
|
||
globtype,Tokens,Version,
|
||
systems,cpubase,
|
||
itcpugas,
|
||
{$if defined(I386) or defined(x64_86)}
|
||
rax86,
|
||
{$endif}
|
||
{$ifdef m68k}
|
||
ag68kgas,
|
||
{$endif}
|
||
{$ifdef USE_EXTERNAL_COMPILER}
|
||
fpintf, { superseeds version_string of version unit }
|
||
{$endif USE_EXTERNAL_COMPILER}
|
||
{$ifndef NODEBUG}
|
||
gdbint,
|
||
{$endif NODEBUG}
|
||
{$ifdef VESA}Vesa,{$endif}
|
||
FPSwitch,FPSymbol,FPDebug,FPVars,FPUtils,FPCompil,FPHelp,
|
||
FPTools,FPIDE,FPCodTmp,FPCodCmp;
|
||
|
||
const
|
||
RSourceEditor: TStreamRec = (
|
||
ObjType: 1500;
|
||
VmtLink: Ofs(TypeOf(TSourceEditor)^);
|
||
Load: @TSourceEditor.Load;
|
||
Store: @TSourceEditor.Store
|
||
);
|
||
RSourceWindow: TStreamRec = (
|
||
ObjType: 1501;
|
||
VmtLink: Ofs(TypeOf(TSourceWindow)^);
|
||
Load: @TSourceWindow.Load;
|
||
Store: @TSourceWindow.Store
|
||
);
|
||
RFPHelpViewer: TStreamRec = (
|
||
ObjType: 1502;
|
||
VmtLink: Ofs(TypeOf(TFPHelpViewer)^);
|
||
Load: @TFPHelpViewer.Load;
|
||
Store: @TFPHelpViewer.Store
|
||
);
|
||
RFPHelpWindow: TStreamRec = (
|
||
ObjType: 1503;
|
||
VmtLink: Ofs(TypeOf(TFPHelpWindow)^);
|
||
Load: @TFPHelpWindow.Load;
|
||
Store: @TFPHelpWindow.Store
|
||
);
|
||
RClipboardWindow: TStreamRec = (
|
||
ObjType: 1504;
|
||
VmtLink: Ofs(TypeOf(TClipboardWindow)^);
|
||
Load: @TClipboardWindow.Load;
|
||
Store: @TClipboardWindow.Store
|
||
);
|
||
RMessageListBox: TStreamRec = (
|
||
ObjType: 1505;
|
||
VmtLink: Ofs(TypeOf(TMessageListBox)^);
|
||
Load: @TMessageListBox.Load;
|
||
Store: @TMessageListBox.Store
|
||
);
|
||
RFPDesktop: TStreamRec = (
|
||
ObjType: 1506;
|
||
VmtLink: Ofs(TypeOf(TFPDesktop)^);
|
||
Load: @TFPDesktop.Load;
|
||
Store: @TFPDesktop.Store
|
||
);
|
||
|
||
RFPASCIIChart: TStreamRec = (
|
||
ObjType: 1509;
|
||
VmtLink: Ofs(TypeOf(TFPASCIIChart)^);
|
||
Load: @TFPASCIIChart.Load;
|
||
Store: @TFPASCIIChart.Store
|
||
);
|
||
RFPDlgWindow: TStreamRec = (
|
||
ObjType: 1511;
|
||
VmtLink: Ofs(TypeOf(TFPDlgWindow)^);
|
||
Load: @TFPDlgWindow.Load;
|
||
Store: @TFPDlgWindow.Store
|
||
);
|
||
{$ifndef NODEBUG}
|
||
RGDBWindow: TStreamRec = (
|
||
ObjType: 1508;
|
||
VmtLink: Ofs(TypeOf(TGDBWindow)^);
|
||
Load: @TGDBWindow.Load;
|
||
Store: @TGDBWindow.Store
|
||
);
|
||
RGDBSourceEditor: TStreamRec = (
|
||
ObjType: 1507;
|
||
VmtLink: Ofs(TypeOf(TGDBSourceEditor)^);
|
||
Load: @TGDBSourceEditor.Load;
|
||
Store: @TGDBSourceEditor.Store
|
||
);
|
||
RDisassemblyEditor: TStreamRec = (
|
||
ObjType: 1512;
|
||
VmtLink: Ofs(TypeOf(TDisassemblyEditor)^);
|
||
Load: @TDisassemblyEditor.Load;
|
||
Store: @TDisassemblyEditor.Store
|
||
);
|
||
RDisassemblyWindow: TStreamRec = (
|
||
ObjType: 1513;
|
||
VmtLink: Ofs(TypeOf(TDisassemblyWindow)^);
|
||
Load: @TDisassemblyWindow.Load;
|
||
Store: @TDisassemblyWindow.Store
|
||
);
|
||
{$endif NODEBUG}
|
||
const
|
||
GlobalNoNameCount : integer = 0;
|
||
var
|
||
ReservedWords : array[1..ReservedWordMaxLen] of PStringCollection;
|
||
AsmReservedWords : array[1..ReservedWordMaxLen] of PStringCollection;
|
||
|
||
{$ifdef useresstrings}
|
||
resourcestring
|
||
{$else}
|
||
const
|
||
{$endif}
|
||
{ Source editor local menu items }
|
||
menu_srclocal_openfileatcursor = 'Open ~f~ile at cursor';
|
||
menu_srclocal_browseatcursor = '~B~rowse symbol at cursor';
|
||
menu_srclocal_topicsearch = 'Topic ~s~earch';
|
||
menu_srclocal_options = '~O~ptions...';
|
||
menu_srclocal_reload = '~R~eload modified file';
|
||
|
||
{ Help viewer local menu items }
|
||
menu_hlplocal_debug = 'Debug infos';
|
||
menu_hlplocal_contents = '~C~ontents';
|
||
menu_hlplocal_index = '~I~ndex';
|
||
menu_hlplocal_topicsearch = '~T~opic search';
|
||
menu_hlplocal_prevtopic = '~P~revious topic';
|
||
menu_hlplocal_copy = '~C~opy';
|
||
|
||
{ Messages local menu items }
|
||
menu_msglocal_clear = '~C~lear';
|
||
menu_msglocal_gotosource = '~G~oto source';
|
||
menu_msglocal_tracksource = '~T~rack source';
|
||
|
||
menu_edit_cut = 'Cu~t~';
|
||
menu_edit_copy = '~C~opy';
|
||
menu_edit_paste = '~P~aste';
|
||
menu_edit_clear = 'C~l~ear';
|
||
|
||
msg_errorreadingfile = 'Error reading file %s';
|
||
msg_loadingfile = 'Loading %s';
|
||
msg_storingfile = 'Storing %s';
|
||
msg_closingfile = 'Closing %s';
|
||
|
||
dialog_gdbwindow = 'GDB window';
|
||
dialog_disaswindow = 'Disassembly window';
|
||
dialog_clipboard = 'Clipboard';
|
||
dialog_userscreen = 'User screen';
|
||
dialog_about = 'About';
|
||
label_about_compilerversion = 'Compiler Version';
|
||
label_about_debugger = 'Debugger';
|
||
|
||
menu_msglocal_saveas = 'Save ~a~s';
|
||
msg_openingsourcefile = 'Opening source file... (%s)';
|
||
msg_readingfileineditor = 'Reading %s into editor...';
|
||
msg_nodebuggersupportavailable = 'No debugger support available.';
|
||
|
||
{****************************************************************************
|
||
TStoreCollection
|
||
****************************************************************************}
|
||
|
||
function TStoreCollection.Add(const S: string): PString;
|
||
var P: PString;
|
||
Index: Sw_integer;
|
||
begin
|
||
if S='' then P:=nil else
|
||
if Search(@S,Index) then P:=At(Index) else
|
||
begin
|
||
P:=NewStr(S);
|
||
Insert(P);
|
||
end;
|
||
Add:=P;
|
||
end;
|
||
|
||
|
||
function IsThereAnyEditor: boolean;
|
||
function EditorWindow(P: PView): boolean;
|
||
begin
|
||
EditorWindow:=(P^.HelpCtx=hcSourceWindow);
|
||
end;
|
||
begin
|
||
IsThereAnyEditor:=Desktop^.FirstThat(@EditorWindow)<>nil;
|
||
end;
|
||
|
||
procedure AskToReloadAllModifiedFiles;
|
||
procedure EditorWindowModifiedOnDisk(P: PView);
|
||
begin
|
||
if (P^.HelpCtx=hcSourceWindow) then
|
||
PSourceWindow(P)^.Editor^.ReloadFile;
|
||
end;
|
||
begin
|
||
Desktop^.ForEach(@EditorWindowModifiedOnDisk);
|
||
end;
|
||
|
||
function IsThereAnyHelpWindow: boolean;
|
||
begin
|
||
IsThereAnyHelpWindow:=(HelpWindow<>nil) and (HelpWindow^.GetState(sfVisible));
|
||
end;
|
||
|
||
function IsThereAnyNumberedWindow: boolean;
|
||
var _Is: boolean;
|
||
begin
|
||
_Is:=Message(Desktop,evBroadcast,cmSearchWindow,nil)<>nil;
|
||
_Is:=_Is or ( (ClipboardWindow<>nil) and ClipboardWindow^.GetState(sfVisible));
|
||
IsThereAnyNumberedWindow:=_Is;
|
||
end;
|
||
|
||
function IsWindow(P: PView): boolean;
|
||
var OK: boolean;
|
||
begin
|
||
OK:=false;
|
||
if (P^.HelpCtx=hcSourceWindow) or
|
||
(P^.HelpCtx=hcHelpWindow) or
|
||
(P^.HelpCtx=hcClipboardWindow) or
|
||
(P^.HelpCtx=hcCalcWindow) or
|
||
(P^.HelpCtx=hcInfoWindow) or
|
||
(P^.HelpCtx=hcBrowserWindow) or
|
||
(P^.HelpCtx=hcMessagesWindow) or
|
||
(P^.HelpCtx=hcCompilerMessagesWindow) or
|
||
(P^.HelpCtx=hcGDBWindow) or
|
||
(P^.HelpCtx=hcdisassemblyWindow) or
|
||
(P^.HelpCtx=hcWatchesWindow) or
|
||
(P^.HelpCtx=hcRegistersWindow) or
|
||
(P^.HelpCtx=hcFPURegisters) or
|
||
(P^.HelpCtx=hcVectorRegisters) or
|
||
(P^.HelpCtx=hcStackWindow) or
|
||
(P^.HelpCtx=hcBreakpointListWindow) or
|
||
(P^.HelpCtx=hcASCIITableWindow)
|
||
then
|
||
OK:=true;
|
||
IsWindow:=OK;
|
||
end;
|
||
|
||
function IsThereAnyWindow: boolean;
|
||
function CheckIt(P: PView): boolean;
|
||
begin
|
||
CheckIt:=IsWindow(P);
|
||
end;
|
||
begin
|
||
IsThereAnyWindow:=Desktop^.FirstThat(@CheckIt)<>nil;
|
||
end;
|
||
|
||
function IsThereAnyVisibleWindow: boolean;
|
||
function CheckIt(P: PView): boolean;
|
||
begin
|
||
CheckIt:=IsWindow(P) and P^.GetState(sfVisible);
|
||
end;
|
||
begin
|
||
IsThereAnyVisibleWindow:=Desktop^.FirstThat(@CheckIt)<>nil;
|
||
end;
|
||
|
||
function FirstEditorWindow: PSourceWindow;
|
||
function EditorWindow(P: PView): boolean;
|
||
begin
|
||
EditorWindow:=(P^.HelpCtx=hcSourceWindow);
|
||
end;
|
||
begin
|
||
FirstEditorWindow:=pointer(Desktop^.FirstThat(@EditorWindow));
|
||
end;
|
||
|
||
function EditorWindowFile(const Name : String): PSourceWindow;
|
||
var
|
||
SName : string;
|
||
|
||
function EditorWindow(P: PView): boolean;
|
||
begin
|
||
EditorWindow:=(TypeOf(P^)=TypeOf(TSourceWindow)) and
|
||
(FixFileName(PSourceWindow(P)^.Editor^.FileName)=SName);
|
||
end;
|
||
|
||
begin
|
||
SName:=FixFileName(FExpand(Name));
|
||
EditorWindowFile:=pointer(Desktop^.FirstThat(@EditorWindow));
|
||
end;
|
||
|
||
|
||
{$ifndef NODEBUG}
|
||
function InDisassemblyWindow :boolean;
|
||
var
|
||
PW : PWindow;
|
||
|
||
function CheckIt(P: PView): boolean;
|
||
begin
|
||
CheckIt:=IsWindow(P) and P^.GetState(sfVisible) and
|
||
(P^.HelpCtx <> hcWatchesWindow) and
|
||
(P^.HelpCtx <> hcStackWindow) and
|
||
(P^.HelpCtx <> hcRegistersWindow) and
|
||
(P^.HelpCtx <> hcVectorRegisters) and
|
||
(P^.HelpCtx <> hcFPURegisters);
|
||
end;
|
||
begin
|
||
PW:=PWindow(Desktop^.FirstThat(@CheckIt));
|
||
InDisassemblyWindow:=Assigned(PW) and
|
||
(TypeOf(PW^)=TypeOf(TDisassemblyWindow));
|
||
end;
|
||
{$endif NODEBUG}
|
||
|
||
|
||
function GetEditorCurWord(Editor: PEditor; ValidSpecChars: TCharSet): string;
|
||
var S: string;
|
||
PS,PE: byte;
|
||
function Trim(S: string): string;
|
||
const TrimChars : set of char = [#0,#9,' ',#255];
|
||
begin
|
||
while (length(S)>0) and (S[1] in TrimChars) do Delete(S,1,1);
|
||
while (length(S)>0) and (S[length(S)] in TrimChars) do Delete(S,length(S),1);
|
||
Trim:=S;
|
||
end;
|
||
const AlphaNum : set of char = ['A'..'Z','0'..'9','_'];
|
||
begin
|
||
with Editor^ do
|
||
begin
|
||
S:=GetDisplayText(CurPos.Y);
|
||
PS:=CurPos.X; while (PS>0) and (Upcase(S[PS]) in AlphaNum) do Dec(PS);
|
||
PE:=CurPos.X; while (PE<length(S)) and (Upcase(S[PE+1]) in (AlphaNum+ValidSpecChars)) do Inc(PE);
|
||
S:=Trim(copy(S,PS+1,PE-PS));
|
||
end;
|
||
GetEditorCurWord:=S;
|
||
end;
|
||
|
||
|
||
{*****************************************************************************
|
||
Tab
|
||
*****************************************************************************}
|
||
|
||
function NewTabItem(AView: PView; ANext: PTabItem): PTabItem;
|
||
var P: PTabItem;
|
||
begin
|
||
New(P); FillChar(P^,SizeOf(P^),0);
|
||
P^.Next:=ANext; P^.View:=AView;
|
||
NewTabItem:=P;
|
||
end;
|
||
|
||
procedure DisposeTabItem(P: PTabItem);
|
||
begin
|
||
if P<>nil then
|
||
begin
|
||
if P^.View<>nil then Dispose(P^.View, Done);
|
||
Dispose(P);
|
||
end;
|
||
end;
|
||
|
||
function NewTabDef(AName: string; ADefItem: PView; AItems: PTabItem; ANext: PTabDef): PTabDef;
|
||
var P: PTabDef;
|
||
x: byte;
|
||
begin
|
||
New(P);
|
||
P^.Next:=ANext; P^.Name:=NewStr(AName); P^.Items:=AItems;
|
||
x:=pos('~',AName);
|
||
if (x<>0) and (x<length(AName)) then P^.ShortCut:=Upcase(AName[x+1])
|
||
else P^.ShortCut:=#0;
|
||
P^.DefItem:=ADefItem;
|
||
NewTabDef:=P;
|
||
end;
|
||
|
||
procedure DisposeTabDef(P: PTabDef);
|
||
var PI,X: PTabItem;
|
||
begin
|
||
DisposeStr(P^.Name);
|
||
PI:=P^.Items;
|
||
while PI<>nil do
|
||
begin
|
||
X:=PI^.Next;
|
||
DisposeTabItem(PI);
|
||
PI:=X;
|
||
end;
|
||
Dispose(P);
|
||
end;
|
||
|
||
|
||
{*****************************************************************************
|
||
Reserved Words
|
||
*****************************************************************************}
|
||
|
||
function GetReservedWordCount: integer;
|
||
var
|
||
Count,I: integer;
|
||
begin
|
||
Count:=0;
|
||
for I:=ord(Low(tToken)) to ord(High(tToken)) do
|
||
with TokenInfo^[TToken(I)] do
|
||
if (str<>'') and (str[1] in['A'..'Z']) and (length(str)>1) then
|
||
Inc(Count);
|
||
GetReservedWordCount:=Count;
|
||
end;
|
||
|
||
function GetReservedWord(Index: integer): string;
|
||
var
|
||
Count,Idx,I: integer;
|
||
S: string;
|
||
begin
|
||
Idx:=-1;
|
||
Count:=-1;
|
||
I:=ord(Low(tToken));
|
||
while (I<=ord(High(tToken))) and (Idx=-1) do
|
||
with TokenInfo^[TToken(I)] do
|
||
begin
|
||
if (str<>'') and (str[1] in['A'..'Z']) and (length(str)>1) then
|
||
begin
|
||
Inc(Count);
|
||
if Count=Index then
|
||
Idx:=I;
|
||
end;
|
||
Inc(I);
|
||
end;
|
||
if Idx=-1 then
|
||
S:=''
|
||
else
|
||
S:=TokenInfo^[TToken(Idx)].str;
|
||
GetReservedWord:=S;
|
||
end;
|
||
|
||
|
||
{$ifdef powerpc}
|
||
{$define USE_TasmCondFlag}
|
||
{$define Use_gas_op2str}
|
||
{$endif}
|
||
{$ifdef powerpc64}
|
||
{$define USE_TasmCondFlag}
|
||
{$define Use_gas_op2str}
|
||
{$endif}
|
||
{$ifdef i386}
|
||
{$define USE_TasmCond}
|
||
{$define Use_std_op2str}
|
||
{$endif}
|
||
{$ifdef m68k}
|
||
{$define USE_None}
|
||
{$define Use_gas_op2str}
|
||
{$endif}
|
||
|
||
function GetAsmReservedWordCount: integer;
|
||
begin
|
||
GetAsmReservedWordCount:=ord(lastop) - ord(firstop)
|
||
{$ifdef Use_TasmCond}
|
||
+ CondAsmOps*(ord(high(TasmCond))-ord(low(TasmCond)));
|
||
{$endif Use_TasmCond}
|
||
{$ifdef Use_TasmCondFlag}
|
||
+ CondAsmOps*(ord(high(TasmCondFlag))-ord(low(TasmCondFlag)));
|
||
{$endif Use_TasmCondFlag}
|
||
{$ifdef Use_None}
|
||
;
|
||
{$endif Use_None}
|
||
end;
|
||
|
||
|
||
{$define NOASM}
|
||
function GetAsmReservedWord(Index: integer): string;
|
||
var
|
||
CondNum,CondOpNum : integer;
|
||
begin
|
||
{$ifdef m68k}
|
||
{$undef NOASM}
|
||
if index <= ord(lastop) - ord(firstop) then
|
||
GetAsmReservedWord:=gas_op2str[tasmop(Index+ord(firstop))]
|
||
else
|
||
GetAsmReservedWord:='';
|
||
(*
|
||
begin
|
||
index:=index - (ord(lastop) - ord(firstop) );
|
||
CondOpNum:= index div (ord(high(TasmCond))-ord(low(TasmCond)));
|
||
CondNum:=index - (CondOpNum * (ord(high(TasmCond))-ord(low(TasmCond))));
|
||
GetAsmReservedWord:=CondAsmOpStr[CondOpNum]+cond2str[TasmCond(CondNum+ord(low(TAsmCond))+1)];
|
||
end;
|
||
*)
|
||
{$else not m68k}
|
||
if index <= ord(lastop) - ord(firstop) then
|
||
{$ifdef Use_gas_op2str}
|
||
GetAsmReservedWord:=gas_op2str[tasmop(Index+ord(firstop))]
|
||
{$endif Use_gas_op2str}
|
||
{$ifdef Use_std_op2str}
|
||
GetAsmReservedWord:=std_op2str[tasmop(Index+ord(firstop))]
|
||
{$endif Use_std_op2str}
|
||
{$ifdef Use_TASMCond}
|
||
{$undef NOASM}
|
||
else
|
||
begin
|
||
index:=index - (ord(lastop) - ord(firstop) );
|
||
CondOpNum:= index div (ord(high(TasmCond))-ord(low(TasmCond)));
|
||
CondNum:=index - (CondOpNum * (ord(high(TasmCond))-ord(low(TasmCond))));
|
||
GetAsmReservedWord:=CondAsmOpStr[CondOpNum]+cond2str[TasmCond(CondNum+ord(low(TAsmCond))+1)];
|
||
end;
|
||
{$endif Use_TASMCond}
|
||
{$ifdef Use_TASMCondFlag}
|
||
{$undef NOASM}
|
||
else
|
||
begin
|
||
index:=index - (ord(lastop) - ord(firstop) );
|
||
CondOpNum:= index div (ord(high(TasmCondFlag))-ord(low(TasmCondFlag)));
|
||
CondNum:=index - (CondOpNum * (ord(high(TasmCondFlag))-ord(low(TasmCondFlag))));
|
||
GetAsmReservedWord:=CondAsmOpStr[CondOpNum]+AsmCondFlag2Str[TasmCondFlag(CondNum+ord(low(TAsmCondFlag))+1)];
|
||
end;
|
||
{$endif Use_TASMCond}
|
||
{$endif not m68k}
|
||
{$ifdef NOASM}
|
||
GetAsmReservedWord:='';
|
||
{$endif NOASM}
|
||
end;
|
||
|
||
procedure InitReservedWords;
|
||
var WordS: string;
|
||
Idx,I,J : sw_integer;
|
||
begin
|
||
InitTokens;
|
||
for I:=Low(ReservedWords) to High(ReservedWords) do
|
||
New(ReservedWords[I], Init(50,10));
|
||
for I:=1 to GetReservedWordCount do
|
||
begin
|
||
WordS:=GetReservedWord(I-1); Idx:=length(WordS);
|
||
if (Idx>=Low(ReservedWords)) and (Idx<=High(ReservedWords)) then
|
||
ReservedWords[Idx]^.Insert(NewStr(WordS));
|
||
end;
|
||
for I:=Low(AsmReservedWords) to High(AsmReservedWords) do
|
||
New(AsmReservedWords[I], Init(50,10));
|
||
for I:=1 to GetAsmReservedWordCount do
|
||
begin
|
||
WordS:=UpcaseStr(GetAsmReservedWord(I-1)); Idx:=length(WordS);
|
||
if (Idx>=Low(AsmReservedWords)) and (Idx<=High(AsmReservedWords)) then
|
||
begin
|
||
if not AsmReservedWords[Idx]^.Search(@WordS, J) then
|
||
AsmReservedWords[Idx]^.Insert(NewStr(WordS));
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure DoneReservedWords;
|
||
var I: integer;
|
||
begin
|
||
for I:=Low(ReservedWords) to High(ReservedWords) do
|
||
if assigned(ReservedWords[I]) then
|
||
begin
|
||
dispose(ReservedWords[I],done);
|
||
ReservedWords[I]:=nil;
|
||
end;
|
||
for I:=Low(AsmReservedWords) to High(AsmReservedWords) do
|
||
if assigned(AsmReservedWords[I]) then
|
||
begin
|
||
dispose(AsmReservedWords[I],done);
|
||
ReservedWords[I]:=nil;
|
||
end;
|
||
DoneTokens;
|
||
end;
|
||
|
||
function IsFPReservedWord(const S: string): boolean;
|
||
var _Is: boolean;
|
||
Idx,Item: sw_integer;
|
||
UpS: string;
|
||
begin
|
||
Idx:=length(S); _Is:=false;
|
||
if (Low(ReservedWords)<=Idx) and (Idx<=High(ReservedWords)) and
|
||
(ReservedWords[Idx]<>nil) and (ReservedWords[Idx]^.Count<>0) then
|
||
begin
|
||
UpS:=UpcaseStr(S);
|
||
_Is:=ReservedWords[Idx]^.Search(@UpS,Item);
|
||
end;
|
||
IsFPReservedWord:=_Is;
|
||
end;
|
||
|
||
function IsFPAsmReservedWord(S: string): boolean;
|
||
var _Is: boolean;
|
||
Idx,Item,Len: sw_integer;
|
||
LastC : Char;
|
||
LastTwo : String[2];
|
||
begin
|
||
Idx:=length(S); _Is:=false;
|
||
if (Low(AsmReservedWords)<=Idx) and (Idx<=High(AsmReservedWords)) and
|
||
(AsmReservedWords[Idx]<>nil) and (AsmReservedWords[Idx]^.Count<>0) then
|
||
begin
|
||
S:=UpcaseStr(S);
|
||
_Is:=AsmReservedWords[Idx]^.Search(@S,Item);
|
||
{$ifdef i386}
|
||
if not _Is and (Length(S)>1) then
|
||
begin
|
||
LastC:=S[Length(S)];
|
||
if LastC in ['B','D','L','Q','S','T','V','W'] then
|
||
begin
|
||
Delete(S,Length(S),1);
|
||
Dec(Idx);
|
||
if (AsmReservedWords[Idx]<>nil) and (AsmReservedWords[Idx]^.Count<>0) then
|
||
_Is:=AsmReservedWords[Idx]^.Search(@S,Item);
|
||
if not _Is and (Length(S)>1) then
|
||
begin
|
||
LastTwo:=S[Length(S)]+LastC;
|
||
if (LastTwo='BL') or
|
||
(LastTwo='WL') or
|
||
(LastTwo='BW') then
|
||
begin
|
||
Delete(S,Length(S),1);
|
||
Dec(Idx);
|
||
if (AsmReservedWords[Idx]<>nil) and (AsmReservedWords[Idx]^.Count<>0) then
|
||
_Is:=AsmReservedWords[Idx]^.Search(@S,Item);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
{$endif i386}
|
||
end;
|
||
IsFPAsmReservedWord:=_Is;
|
||
end;
|
||
|
||
|
||
{*****************************************************************************
|
||
SearchWindow
|
||
*****************************************************************************}
|
||
|
||
function SearchWindowWithNo(No: integer): PWindow;
|
||
var P: PWindow;
|
||
begin
|
||
P:=Message(Desktop,evBroadcast,cmSearchWindow+No,nil);
|
||
if pointer(P)=pointer(Desktop) then P:=nil;
|
||
SearchWindowWithNo:=P;
|
||
end;
|
||
|
||
function SearchWindow(const Title: string): PWindow;
|
||
function Match(P: PView): boolean;
|
||
var W: PWindow;
|
||
OK: boolean;
|
||
begin
|
||
W:=nil;
|
||
{ we have a crash here because of the TStatusLine
|
||
that can also have one of these values
|
||
but is not a Window object PM }
|
||
if P<>pointer(StatusLine) then
|
||
if IsWindow(P) then
|
||
W:=PWindow(P);
|
||
OK:=(W<>nil);
|
||
if OK then
|
||
begin
|
||
OK:=CompareText(W^.GetTitle(255),Title)=0;
|
||
end;
|
||
Match:=OK;
|
||
end;
|
||
var W: PView;
|
||
begin
|
||
W:=Application^.FirstThat(@Match);
|
||
{ This is wrong because TStatusLine is also considered PM }
|
||
if not Assigned(W) then W:=Desktop^.FirstThat(@Match);
|
||
{ But why do we need to check all ??
|
||
Probably because of the ones which were not inserted into
|
||
Desktop as the Messages view
|
||
|
||
Exactly. Some windows are inserted directly in the Application and not
|
||
in the Desktop. btw. Does TStatusLine.HelpCtx really change? Why?
|
||
Only GetHelpCtx should return different values depending on the
|
||
focused view (and it's helpctx), but TStatusLine's HelpCtx field
|
||
shouldn't change... Gabor
|
||
|
||
if Assigned(W)=false then W:=Desktop^.FirstThat(@Match);}
|
||
SearchWindow:=PWindow(W);
|
||
end;
|
||
|
||
function SearchFreeWindowNo: integer;
|
||
var No: integer;
|
||
begin
|
||
No:=1;
|
||
while (No<100) and (SearchWindowWithNo(No)<>nil) do
|
||
Inc(No);
|
||
if No=100 then No:=0;
|
||
SearchFreeWindowNo:=No;
|
||
end;
|
||
|
||
|
||
{*****************************************************************************
|
||
TIntegerLine
|
||
*****************************************************************************}
|
||
|
||
constructor TIntegerLine.Init(var Bounds: TRect; AMin, AMax: longint);
|
||
begin
|
||
if inherited Init(Bounds, Bounds.B.X-Bounds.A.X-1)=false then
|
||
Fail;
|
||
Validator:=New(PRangeValidator, Init(AMin, AMax));
|
||
end;
|
||
|
||
|
||
{*****************************************************************************
|
||
SourceEditor
|
||
*****************************************************************************}
|
||
|
||
function SearchCoreForFileName(AFileName: string): PCodeEditorCore;
|
||
var EC: PCodeEditorCore;
|
||
function Check(P: PView): boolean;
|
||
var OK: boolean;
|
||
begin
|
||
OK:=P^.HelpCtx=hcSourceWindow;
|
||
if OK then
|
||
with PSourceWindow(P)^ do
|
||
if FixFileName(Editor^.FileName)=AFileName then
|
||
begin
|
||
EC:=Editor^.Core;
|
||
OK:=true;
|
||
end
|
||
else
|
||
OK:=false;
|
||
Check:=OK;
|
||
end;
|
||
begin
|
||
EC:=nil;
|
||
AFileName:=FixFileName(AFileName);
|
||
{ do not use the same core for all new files }
|
||
if AFileName<>'' then
|
||
Desktop^.FirstThat(@Check);
|
||
SearchCoreForFileName:=EC;
|
||
end;
|
||
|
||
constructor TSourceEditor.Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
|
||
PScrollBar; AIndicator: PIndicator;const AFileName: string);
|
||
var EC: PCodeEditorCore;
|
||
begin
|
||
EC:=SearchCoreForFileName(AFileName);
|
||
inherited Init(Bounds,AHScrollBar,AVScrollBar,AIndicator,EC,AFileName);
|
||
SetStoreUndo(true);
|
||
CompileStamp:=0;
|
||
end;
|
||
|
||
Const
|
||
FreePascalSpecSymbolCount : array [TSpecSymbolClass] of integer =
|
||
(
|
||
3,{ssCommentPrefix}
|
||
1,{ssCommentSingleLinePrefix}
|
||
2,{ssCommentSuffix}
|
||
1,{ssStringPrefix}
|
||
1,{ssStringSuffix}
|
||
1,{ssDirectivePrefix}
|
||
1,{ssDirectiveSuffix}
|
||
1,{ssAsmPrefix}
|
||
1 {ssAsmSuffix}
|
||
);
|
||
|
||
FreePascalEmptyString : string[1] = '';
|
||
FreePascalCommentPrefix1 : string[1] = '{';
|
||
FreePascalCommentPrefix2 : string[2] = '(*';
|
||
FreePascalCommentPrefix3 : string[2] = '//';
|
||
FreePascalCommentSingleLinePrefix : string[2] = '//';
|
||
FreePascalCommentSuffix1 : string[1] = '}';
|
||
FreePascalCommentSuffix2 : string[2] = '*)';
|
||
FreePascalStringPrefix : string[1] = '''';
|
||
FreePascalStringSuffix : string[1] = '''';
|
||
FreePascalDirectivePrefix : string[2] = '{$';
|
||
FreePascalDirectiveSuffix : string[1] = '}';
|
||
FreePascalAsmPrefix : string[3] = 'ASM';
|
||
FreePascalAsmSuffix : string[3] = 'END';
|
||
|
||
function TSourceEditor.GetSpecSymbolCount(SpecClass: TSpecSymbolClass): integer;
|
||
begin
|
||
GetSpecSymbolCount:=FreePascalSpecSymbolCount[SpecClass];
|
||
end;
|
||
|
||
function TSourceEditor.GetSpecSymbol(SpecClass: TSpecSymbolClass; Index: integer): pstring;
|
||
begin
|
||
GetSpecSymbol:=@FreePascalEmptyString;
|
||
case SpecClass of
|
||
ssCommentPrefix :
|
||
case Index of
|
||
0 : GetSpecSymbol:=@FreePascalCommentPrefix1;
|
||
1 : GetSpecSymbol:=@FreePascalCommentPrefix2;
|
||
2 : GetSpecSymbol:=@FreePascalCommentPrefix3;
|
||
end;
|
||
ssCommentSingleLinePrefix :
|
||
case Index of
|
||
0 : GetSpecSymbol:=@FreePascalCommentSingleLinePrefix;
|
||
end;
|
||
ssCommentSuffix :
|
||
case Index of
|
||
0 : GetSpecSymbol:=@FreePascalCommentSuffix1;
|
||
1 : GetSpecSymbol:=@FreePascalCommentSuffix2;
|
||
end;
|
||
ssStringPrefix :
|
||
GetSpecSymbol:=@FreePascalStringPrefix;
|
||
ssStringSuffix :
|
||
GetSpecSymbol:=@FreePascalStringSuffix;
|
||
{ must be uppercased to avoid calling UpCaseStr in MatchesAnyAsmSymbol PM }
|
||
ssAsmPrefix :
|
||
GetSpecSymbol:=@FreePascalAsmPrefix;
|
||
ssAsmSuffix :
|
||
GetSpecSymbol:=@FreePascalAsmSuffix;
|
||
ssDirectivePrefix :
|
||
GetSpecSymbol:=@FreePascalDirectivePrefix;
|
||
ssDirectiveSuffix :
|
||
GetSpecSymbol:=@FreePascalDirectiveSuffix;
|
||
end;
|
||
end;
|
||
|
||
function TSourceEditor.IsReservedWord(const S: string): boolean;
|
||
begin
|
||
IsReservedWord:=IsFPReservedWord(S);
|
||
end;
|
||
|
||
function TSourceEditor.IsAsmReservedWord(const S: string): boolean;
|
||
begin
|
||
IsAsmReservedWord:=IsFPAsmReservedWord(S);
|
||
end;
|
||
|
||
function TSourceEditor.TranslateCodeTemplate(var Shortcut: string; ALines: PUnsortedStringCollection): boolean;
|
||
begin
|
||
TranslateCodeTemplate:=FPTranslateCodeTemplate(ShortCut,ALines);
|
||
end;
|
||
|
||
function TSourceEditor.SelectCodeTemplate(var ShortCut: string): boolean;
|
||
var D: PCodeTemplatesDialog;
|
||
OK: boolean;
|
||
begin
|
||
New(D, Init(true,ShortCut));
|
||
OK:=Desktop^.ExecView(D)=cmOK;
|
||
if OK then ShortCut:=D^.GetSelectedShortCut;
|
||
Dispose(D, Done);
|
||
SelectCodeTemplate:=OK;
|
||
end;
|
||
|
||
function TSourceEditor.CompleteCodeWord(const WordS: string; var Text: string): boolean;
|
||
begin
|
||
CompleteCodeWord:=FPCompleteCodeWord(WordS,Text);
|
||
end;
|
||
|
||
procedure TSourceEditor.FindMatchingDelimiter(ScanForward: boolean);
|
||
var
|
||
St,nextResWord : String;
|
||
LineText,LineAttr: string;
|
||
Res,found,addit : boolean;
|
||
JumpPos: TPoint;
|
||
X,Y,lexchange,curlevel,linecount : sw_integer;
|
||
|
||
function GetLexChange(const S : string) : sw_integer;
|
||
begin
|
||
if (S='END') or (S='THEN') or (S='UNTIL') then
|
||
GetLexChange:=-1
|
||
else if (S='ASM') or (S='BEGIN') or (S='CASE') or (S='CLASS') or
|
||
(S='IF') or (S='OBJECT') or (S='RECORD') or (S='REPEAT') then
|
||
GetLexChange:=+1
|
||
else
|
||
GetLexChange:=0;
|
||
end;
|
||
|
||
begin
|
||
st:=UpcaseStr(GetCurrentWord);
|
||
if st<>'' then
|
||
Res:=IsReservedWord(St)
|
||
else
|
||
Res:=false;
|
||
LexChange:=GetLexChange(St);
|
||
if not res or (LexChange=0) or not
|
||
IsFlagSet(efSyntaxHighlight) then
|
||
Inherited FindMatchingDelimiter(ScanForward)
|
||
else
|
||
begin
|
||
JumpPos.X:=-1; JumpPos.Y:=-1;
|
||
Y:=CurPos.Y; X:=CurPos.X;
|
||
found:=false;
|
||
LineCount:=0;
|
||
curlevel:=lexchange;
|
||
if LexChange>0 then
|
||
begin
|
||
repeat
|
||
Inc(LineCount);
|
||
NextResWord:='';
|
||
GetDisplayTextFormat(Y,LineText,LineAttr);
|
||
if LineCount<>1 then X:=-1
|
||
else if ord(LineAttr[X+1])<>coReservedWordColor then
|
||
exit;
|
||
repeat
|
||
Inc(X);
|
||
if X<length(LineText) then
|
||
begin
|
||
AddIt:=ord(LineAttr[X+1])=coReservedWordColor;
|
||
if AddIt then
|
||
NextResWord:=NextResWord+UpCase(LineText[X+1]);
|
||
end;
|
||
if ((X=length(LineText)) or (Not AddIt)) and
|
||
(NextResWord<>'') and
|
||
IsReservedWord(NextResWord) then
|
||
begin
|
||
LexChange:=GetLexChange(NextResWord);
|
||
CurLevel:=CurLevel+LexChange;
|
||
if CurLevel=0 then
|
||
begin
|
||
JumpPos.X:=X-Length(NextResWord);
|
||
JumpPos.Y:=Y;
|
||
end;
|
||
NextResWord:='';
|
||
end;
|
||
until (X>=length(LineText)) or (JumpPos.X<>-1);
|
||
Inc(Y);
|
||
until (Y>=GetLineCount) or (JumpPos.X<>-1);
|
||
if (Y=GetLineCount) and (JumpPos.X=-1) then
|
||
begin
|
||
ErrorBox('No match',nil);
|
||
exit;
|
||
end;
|
||
end
|
||
else if (LexChange<0) then
|
||
begin
|
||
repeat
|
||
Inc(LineCount);
|
||
NextResWord:='';
|
||
GetDisplayTextFormat(Y,LineText,LineAttr);
|
||
if LineCount<>1 then
|
||
X:=Length(LineText)
|
||
else if ord(LineAttr[X+1])<>coReservedWordColor then
|
||
exit;
|
||
repeat
|
||
Dec(X);
|
||
if X>=0 then
|
||
begin
|
||
AddIt:=ord(LineAttr[X+1])=coReservedWordColor;
|
||
if AddIt then
|
||
NextResWord:=UpCase(LineText[X+1])+NextResWord;
|
||
end;
|
||
if ((X=0) or (Not AddIt)) and
|
||
(NextResWord<>'') and
|
||
IsReservedWord(NextResWord) then
|
||
begin
|
||
LexChange:=GetLexChange(NextResWord);
|
||
CurLevel:=CurLevel+LexChange;
|
||
if CurLevel=0 then
|
||
begin
|
||
if AddIt then
|
||
JumpPos.X:=X
|
||
else
|
||
JumpPos.X:=X+1;
|
||
JumpPos.Y:=Y;
|
||
end;
|
||
NextResWord:='';
|
||
end;
|
||
until (X<=0) or (JumpPos.X<>-1);
|
||
Dec(Y);
|
||
until (Y<0) or (JumpPos.X<>-1);
|
||
if (Y<0) and (JumpPos.X=-1) then
|
||
begin
|
||
ErrorBox('No match',nil);
|
||
exit;
|
||
end;
|
||
end;
|
||
if JumpPos.X<>-1 then
|
||
begin
|
||
SetCurPtr(JumpPos.X,JumpPos.Y);
|
||
TrackCursor(do_centre);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TSourceEditor.SetCodeCompleteWord(const S: string);
|
||
var R: TRect;
|
||
begin
|
||
inherited SetCodeCompleteWord(S);
|
||
if S='' then
|
||
begin
|
||
if Assigned(CodeCompleteTip) then Dispose(CodeCompleteTip, Done);
|
||
CodeCompleteTip:=nil;
|
||
end
|
||
else
|
||
begin
|
||
R.Assign(0,0,20,1);
|
||
if Assigned(CodeCompleteTip)=false then
|
||
begin
|
||
New(CodeCompleteTip, Init(R, S, alCenter));
|
||
CodeCompleteTip^.Hide;
|
||
Application^.Insert(CodeCompleteTip);
|
||
end
|
||
else
|
||
CodeCompleteTip^.SetText(S);
|
||
AlignCodeCompleteTip;
|
||
end;
|
||
end;
|
||
|
||
procedure TSourceEditor.AlignCodeCompleteTip;
|
||
var P: TPoint;
|
||
S: string;
|
||
R: TRect;
|
||
begin
|
||
if Assigned(CodeCompleteTip)=false then Exit;
|
||
S:=CodeCompleteTip^.GetText;
|
||
P.Y:=CurPos.Y;
|
||
{ determine the center of current word fragment }
|
||
P.X:=CurPos.X-(length(GetCodeCompleteFrag) div 2);
|
||
{ calculate position for centering the complete word over/below the current }
|
||
P.X:=P.X-(length(S) div 2);
|
||
|
||
P.X:=P.X-Delta.X;
|
||
P.Y:=P.Y-Delta.Y;
|
||
MakeGlobal(P,P);
|
||
if Assigned(CodeCompleteTip^.Owner) then
|
||
CodeCompleteTip^.Owner^.MakeLocal(P,P);
|
||
|
||
{ ensure that the tooltip stays in screen }
|
||
P.X:=Min(Max(0,P.X),ScreenWidth-length(S)-2-1);
|
||
{ align it vertically }
|
||
if P.Y>round(ScreenHeight*3/4) then
|
||
Dec(P.Y)
|
||
else
|
||
Inc(P.Y);
|
||
R.Assign(P.X,P.Y,P.X+1+length(S)+1,P.Y+1);
|
||
CodeCompleteTip^.Locate(R);
|
||
if CodeCompleteTip^.GetState(sfVisible)=false then
|
||
CodeCompleteTip^.Show;
|
||
end;
|
||
|
||
procedure TSourceEditor.ModifiedChanged;
|
||
begin
|
||
inherited ModifiedChanged;
|
||
if (@Self<>Clipboard) and GetModified then
|
||
begin
|
||
{ global flags }
|
||
EditorModified:=true;
|
||
{ reset compile flags as the file is
|
||
not the same as at the compilation anymore }
|
||
CompileStamp:=-1;
|
||
end;
|
||
end;
|
||
|
||
procedure TSourceEditor.InsertOptions;
|
||
var C: PUnsortedStringCollection;
|
||
Y: sw_integer;
|
||
S: string;
|
||
begin
|
||
Lock;
|
||
New(C, Init(10,10));
|
||
GetCompilerOptionLines(C);
|
||
if C^.Count>0 then
|
||
begin
|
||
for Y:=0 to C^.Count-1 do
|
||
begin
|
||
S:=C^.At(Y)^;
|
||
InsertLine(Y,S);
|
||
end;
|
||
AdjustSelectionPos(0,0,0,C^.Count);
|
||
UpdateAttrs(0,attrAll);
|
||
DrawLines(0);
|
||
SetModified(true);
|
||
end;
|
||
Dispose(C, Done);
|
||
UnLock;
|
||
end;
|
||
|
||
procedure TSourceEditor.PushInfo(Const st : string);
|
||
begin
|
||
PushStatus(st);
|
||
end;
|
||
|
||
procedure TSourceEditor.PopInfo;
|
||
begin
|
||
PopStatus;
|
||
end;
|
||
|
||
procedure TSourceEditor.DeleteLine(I: sw_integer);
|
||
begin
|
||
inherited DeleteLine(I);
|
||
{$ifndef NODEBUG}
|
||
If ShouldHandleBreakpoints then
|
||
BreakpointsCollection^.AdaptBreakpoints(@Self,I,-1);
|
||
{$endif NODEBUG}
|
||
end;
|
||
|
||
procedure TSourceEditor.BackSpace;
|
||
{$ifndef NODEBUG}
|
||
var
|
||
MoveBreakpointToPreviousLine,WasEnabled : boolean;
|
||
PBStart,PBEnd : PBreakpoint;
|
||
I : longint;
|
||
{$endif NODEBUG}
|
||
begin
|
||
{$ifdef NODEBUG}
|
||
inherited Backspace;
|
||
{$else}
|
||
MoveBreakpointToPreviousLine:=(CurPos.X=0) and (CurPos.Y>0);
|
||
If MoveBreakpointToPreviousLine then
|
||
begin
|
||
ShouldHandleBreakpoints:=false;
|
||
I:=CurPos.Y+1;
|
||
PBEnd:=BreakpointsCollection^.FindBreakpointAt(@Self,I);
|
||
PBStart:=BreakpointsCollection^.FindBreakpointAt(@Self,I-1);
|
||
end;
|
||
inherited Backspace;
|
||
if MoveBreakpointToPreviousLine then
|
||
begin
|
||
ShouldHandleBreakpoints:=true;
|
||
if assigned(PBEnd) then
|
||
begin
|
||
if assigned(PBStart) then
|
||
begin
|
||
if PBEnd^.state=bs_enabled then
|
||
PBStart^.state:=bs_enabled;
|
||
BreakpointsCollection^.Free(PBEnd);
|
||
end
|
||
else
|
||
begin
|
||
WasEnabled:=PBEnd^.state=bs_enabled;
|
||
if WasEnabled then
|
||
begin
|
||
PBEnd^.state:=bs_disabled;
|
||
PBEnd^.UpdateSource;
|
||
end;
|
||
PBEnd^.line:=I-1;
|
||
if WasEnabled then
|
||
begin
|
||
PBEnd^.state:=bs_enabled;
|
||
PBEnd^.UpdateSource;
|
||
end;
|
||
end;
|
||
end;
|
||
BreakpointsCollection^.AdaptBreakpoints(@Self,I,-1);
|
||
end;
|
||
{$endif NODEBUG}
|
||
end;
|
||
|
||
function TSourceEditor.InsertNewLine : Sw_integer;
|
||
{$ifndef NODEBUG}
|
||
var
|
||
MoveBreakpointToNextLine : boolean;
|
||
I : longint;
|
||
{$endif NODEBUG}
|
||
begin
|
||
{$ifdef NODEBUG}
|
||
InsertNewLine:=inherited InsertNewLine;
|
||
{$else}
|
||
ShouldHandleBreakpoints:=false;
|
||
MoveBreakpointToNextLine:=Cursor.x<Length(RTrim(GetDisplayText(CurPos.Y)));
|
||
I:=CurPos.Y+1;
|
||
InsertNewLine:=inherited InsertNewLine;
|
||
if MoveBreakpointToNextLine then
|
||
BreakpointsCollection^.AdaptBreakpoints(@Self,I-1,1)
|
||
else
|
||
BreakpointsCollection^.AdaptBreakpoints(@Self,I,1);
|
||
ShouldHandleBreakpoints:=true;
|
||
{$endif NODEBUG}
|
||
end;
|
||
|
||
procedure TSourceEditor.DelChar;
|
||
var
|
||
S: string;
|
||
I,CI : sw_integer;
|
||
{$ifndef NODEBUG}
|
||
PBStart,PBEnd : PBreakpoint;
|
||
MoveBreakpointOneLineUp,WasEnabled : boolean;
|
||
{$endif NODEBUG}
|
||
begin
|
||
if IsReadOnly then Exit;
|
||
S:=GetLineText(CurPos.Y);
|
||
I:=CurPos.Y+1;
|
||
CI:=LinePosToCharIdx(CurPos.Y,CurPos.X);
|
||
{$ifndef NODEBUG}
|
||
if ((CI>length(S)) or (S='')) and (CurPos.Y<GetLineCount-1) then
|
||
begin
|
||
MoveBreakpointOneLineUp:=true;
|
||
ShouldHandleBreakpoints:=false;
|
||
PBEnd:=BreakpointsCollection^.FindBreakpointAt(@Self,I+1);
|
||
PBStart:=BreakpointsCollection^.FindBreakpointAt(@Self,I);
|
||
end
|
||
else
|
||
MoveBreakpointOneLineUp:=false;
|
||
{$endif NODEBUG}
|
||
Inherited DelChar;
|
||
{$ifndef NODEBUG}
|
||
if MoveBreakpointOneLineUp then
|
||
begin
|
||
ShouldHandleBreakpoints:=true;
|
||
if assigned(PBEnd) then
|
||
begin
|
||
if assigned(PBStart) then
|
||
begin
|
||
if PBEnd^.state=bs_enabled then
|
||
PBStart^.state:=bs_enabled;
|
||
BreakpointsCollection^.Free(PBEnd);
|
||
end
|
||
else
|
||
begin
|
||
WasEnabled:=PBEnd^.state=bs_enabled;
|
||
if WasEnabled then
|
||
begin
|
||
PBEnd^.state:=bs_disabled;
|
||
PBEnd^.UpdateSource;
|
||
end;
|
||
PBEnd^.line:=I;
|
||
if WasEnabled then
|
||
begin
|
||
PBEnd^.state:=bs_enabled;
|
||
PBEnd^.UpdateSource;
|
||
end;
|
||
end;
|
||
end;
|
||
BreakpointsCollection^.AdaptBreakpoints(@Self,I,-1);
|
||
end;
|
||
{$endif NODEBUG}
|
||
end;
|
||
|
||
procedure TSourceEditor.DelSelect;
|
||
{$ifndef NODEBUG}
|
||
var
|
||
MoveBreakpointToFirstLine,WasEnabled : boolean;
|
||
PBStart,PBEnd : PBreakpoint;
|
||
I,J : longint;
|
||
{$endif NODEBUG}
|
||
begin
|
||
{$ifdef NODEBUG}
|
||
inherited DelSelect;
|
||
{$else}
|
||
ShouldHandleBreakpoints:=false;
|
||
J:=SelEnd.Y-SelStart.Y;
|
||
MoveBreakpointToFirstLine:=J>0;
|
||
PBEnd:=BreakpointsCollection^.FindBreakpointAt(@Self,SelEnd.Y);
|
||
PBStart:=BreakpointsCollection^.FindBreakpointAt(@Self,SelEnd.Y);
|
||
I:=SelStart.Y;
|
||
inherited DelSelect;
|
||
if MoveBreakpointToFirstLine and assigned(PBEnd) then
|
||
begin
|
||
If assigned(PBStart) then
|
||
begin
|
||
if PBEnd^.state=bs_enabled then
|
||
PBStart^.state:=bs_enabled;
|
||
BreakpointsCollection^.Free(PBEnd);
|
||
end
|
||
else
|
||
begin
|
||
WasEnabled:=PBEnd^.state=bs_enabled;
|
||
if WasEnabled then
|
||
begin
|
||
PBEnd^.state:=bs_disabled;
|
||
PBEnd^.UpdateSource;
|
||
end;
|
||
PBEnd^.line:=I;
|
||
if WasEnabled then
|
||
begin
|
||
PBEnd^.state:=bs_enabled;
|
||
PBEnd^.UpdateSource;
|
||
end;
|
||
end;
|
||
end;
|
||
BreakpointsCollection^.AdaptBreakpoints(@Self,I,-J);
|
||
ShouldHandleBreakpoints:=true;
|
||
{$endif NODEBUG}
|
||
end;
|
||
|
||
|
||
function TSourceEditor.InsertLine(LineNo: sw_integer; const S: string): PCustomLine;
|
||
begin
|
||
InsertLine := inherited InsertLine(LineNo,S);
|
||
{$ifndef NODEBUG}
|
||
If ShouldHandleBreakpoints then
|
||
BreakpointsCollection^.AdaptBreakpoints(@Self,LineNo,1);
|
||
{$endif NODEBUG}
|
||
end;
|
||
|
||
procedure TSourceEditor.AddLine(const S: string);
|
||
begin
|
||
inherited AddLine(S);
|
||
{$ifndef NODEBUG}
|
||
BreakpointsCollection^.AdaptBreakpoints(@Self,GetLineCount,1);
|
||
{$endif NODEBUG}
|
||
end;
|
||
|
||
|
||
|
||
function TSourceEditor.GetLocalMenu: PMenu;
|
||
var M: PMenu;
|
||
MI: PMenuItem;
|
||
begin
|
||
MI:=
|
||
NewItem(menu_edit_cut,menu_key_edit_cut,cut_key,cmCut,hcCut,
|
||
NewItem(menu_edit_copy,menu_key_edit_copy,copy_key,cmCopy,hcCopy,
|
||
NewItem(menu_edit_paste,menu_key_edit_paste,paste_key,cmPaste,hcPaste,
|
||
NewItem(menu_edit_clear,menu_key_edit_clear,kbCtrlDel,cmClear,hcClear,
|
||
NewLine(
|
||
NewItem(menu_srclocal_openfileatcursor,'',kbNoKey,cmOpenAtCursor,hcOpenAtCursor,
|
||
NewItem(menu_srclocal_browseatcursor,'',kbNoKey,cmBrowseAtCursor,hcBrowseAtCursor,
|
||
NewItem(menu_srclocal_topicsearch,menu_key_help_topicsearch,kbCtrlF1,cmHelpTopicSearch,hcHelpTopicSearch,
|
||
NewLine(
|
||
NewItem(menu_srclocal_options,'',kbNoKey,cmEditorOptions,hcEditorOptions,
|
||
nil))))))))));
|
||
if IsChangedOnDisk then
|
||
MI:=NewItem(menu_srclocal_reload,'',kbNoKey,cmDoReload,hcDoReload,
|
||
MI);
|
||
M:=NewMenu(MI);
|
||
GetLocalMenu:=M;
|
||
end;
|
||
|
||
function TSourceEditor.GetCommandTarget: PView;
|
||
begin
|
||
GetCommandTarget:=@Self;
|
||
end;
|
||
|
||
function TSourceEditor.CreateLocalMenuView(var Bounds: TRect; M: PMenu): PMenuPopup;
|
||
var MV: PAdvancedMenuPopup;
|
||
begin
|
||
New(MV, Init(Bounds,M));
|
||
CreateLocalMenuView:=MV;
|
||
end;
|
||
|
||
{$ifdef DebugUndo}
|
||
procedure TSourceEditor.DumpUndo;
|
||
var
|
||
i : sw_integer;
|
||
begin
|
||
ClearToolMessages;
|
||
AddToolCommand('UndoList Dump');
|
||
for i:=0 to Core^.UndoList^.count-1 do
|
||
with Core^.UndoList^.At(i)^ do
|
||
begin
|
||
if is_grouped_action then
|
||
AddToolMessage('','Group '+ActionString[action]+' '+IntToStr(ActionCount)+' elementary actions',0,0)
|
||
else
|
||
AddToolMessage('',ActionString[action]+' '+IntToStr(StartPos.Y+1)+':'+IntToStr(StartPos.X+1)+
|
||
' '+IntToStr(EndPos.Y+1)+':'+IntToStr(EndPos.X+1)+' "'+GetStr(Text)+'"',0,0);
|
||
end;
|
||
if Core^.RedoList^.count>0 then
|
||
AddToolCommand('RedoList Dump');
|
||
for i:=0 to Core^.RedoList^.count-1 do
|
||
with Core^.RedoList^.At(i)^ do
|
||
begin
|
||
if is_grouped_action then
|
||
AddToolMessage('','Group '+ActionString[action]+' '+IntToStr(ActionCount)+' elementary actions',0,0)
|
||
else
|
||
AddToolMessage('',ActionString[action]+' '+IntToStr(StartPos.Y+1)+':'+IntToStr(StartPos.X+1)+
|
||
' '+IntToStr(EndPos.Y+1)+':'+IntToStr(EndPos.X+1)+' "'+GetStr(Text)+'"',0,0);
|
||
end;
|
||
UpdateToolMessages;
|
||
if Assigned(MessagesWindow) then
|
||
MessagesWindow^.Focus;
|
||
end;
|
||
|
||
procedure TSourceEditor.UndoAll;
|
||
begin
|
||
While Core^.UndoList^.count>0 do
|
||
Undo;
|
||
end;
|
||
|
||
procedure TSourceEditor.RedoAll;
|
||
begin
|
||
While Core^.RedoList^.count>0 do
|
||
Redo;
|
||
end;
|
||
|
||
{$endif DebugUndo}
|
||
|
||
function TSourceEditor.Valid(Command: Word): Boolean;
|
||
var OK: boolean;
|
||
begin
|
||
OK:=inherited Valid(Command);
|
||
if OK and ({(Command=cmClose) or already handled in TFileEditor.Valid PM }
|
||
(Command=cmAskSaveAll)) then
|
||
if IsClipboard=false then
|
||
OK:=SaveAsk(false);
|
||
Valid:=OK;
|
||
end;
|
||
|
||
|
||
procedure TSourceEditor.HandleEvent(var Event: TEvent);
|
||
var DontClear: boolean;
|
||
S: string;
|
||
begin
|
||
TranslateMouseClick(@Self,Event);
|
||
case Event.What of
|
||
evKeyDown :
|
||
begin
|
||
DontClear:=false;
|
||
case Event.KeyCode of
|
||
kbCtrlEnter :
|
||
Message(@Self,evCommand,cmOpenAtCursor,nil);
|
||
else DontClear:=true;
|
||
end;
|
||
if not DontClear then ClearEvent(Event);
|
||
end;
|
||
end;
|
||
inherited HandleEvent(Event);
|
||
case Event.What of
|
||
evBroadcast :
|
||
case Event.Command of
|
||
cmCalculatorPaste :
|
||
begin
|
||
InsertText(FloatToStr(CalcClipboard,0));
|
||
ClearEvent(Event);
|
||
end;
|
||
end;
|
||
evCommand :
|
||
begin
|
||
DontClear:=false;
|
||
case Event.Command of
|
||
{$ifdef DebugUndo}
|
||
cmDumpUndo : DumpUndo;
|
||
cmUndoAll : UndoAll;
|
||
cmRedoAll : RedoAll;
|
||
{$endif DebugUndo}
|
||
cmDoReload : ReloadFile;
|
||
cmBrowseAtCursor:
|
||
begin
|
||
S:=LowerCaseStr(GetEditorCurWord(@Self,[]));
|
||
OpenOneSymbolBrowser(S);
|
||
end;
|
||
cmOpenAtCursor :
|
||
begin
|
||
S:=LowerCaseStr(GetEditorCurWord(@Self,['.']));
|
||
if Pos('.',S)<>0 then
|
||
OpenFileName:=S else
|
||
OpenFileName:=S+'.pp'+ListSeparator+
|
||
S+'.pas'+ListSeparator+
|
||
S+'.inc';
|
||
Message(Application,evCommand,cmOpen,nil);
|
||
end;
|
||
cmEditorOptions :
|
||
Message(Application,evCommand,cmEditorOptions,@Self);
|
||
cmHelp :
|
||
Message(@Self,evCommand,cmHelpTopicSearch,@Self);
|
||
cmHelpTopicSearch :
|
||
HelpTopicSearch(@Self);
|
||
else DontClear:=true;
|
||
end;
|
||
if not DontClear then ClearEvent(Event);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
constructor TFPHeapView.Init(var Bounds: TRect);
|
||
begin
|
||
if inherited Init(Bounds)=false then Fail;
|
||
Options:=Options or gfGrowHiX or gfGrowHiY;
|
||
EventMask:=EventMask or evIdle;
|
||
GrowMode:=gfGrowAll;
|
||
end;
|
||
|
||
constructor TFPHeapView.InitKb(var Bounds: TRect);
|
||
begin
|
||
if inherited InitKb(Bounds)=false then Fail;
|
||
Options:=Options or gfGrowHiX or gfGrowHiY;
|
||
EventMask:=EventMask or evIdle;
|
||
GrowMode:=gfGrowAll;
|
||
end;
|
||
|
||
procedure TFPHeapView.HandleEvent(var Event: TEvent);
|
||
begin
|
||
case Event.What of
|
||
evIdle :
|
||
Update;
|
||
end;
|
||
inherited HandleEvent(Event);
|
||
end;
|
||
|
||
constructor TFPClockView.Init(var Bounds: TRect);
|
||
begin
|
||
inherited Init(Bounds);
|
||
EventMask:=EventMask or evIdle;
|
||
end;
|
||
|
||
procedure TFPClockView.HandleEvent(var Event: TEvent);
|
||
begin
|
||
case Event.What of
|
||
evIdle :
|
||
Update;
|
||
end;
|
||
inherited HandleEvent(Event);
|
||
end;
|
||
|
||
function TFPClockView.GetPalette: PPalette;
|
||
const P: string[length(CFPClockView)] = CFPClockView;
|
||
begin
|
||
GetPalette:=@P;
|
||
end;
|
||
|
||
procedure TFPWindow.SetState(AState: Word; Enable: Boolean);
|
||
var OldState: word;
|
||
begin
|
||
OldState:=State;
|
||
inherited SetState(AState,Enable);
|
||
if AutoNumber then
|
||
if (AState and (sfVisible+sfExposed))<>0 then
|
||
if GetState(sfVisible+sfExposed) then
|
||
begin
|
||
if Number=0 then
|
||
Number:=SearchFreeWindowNo;
|
||
ReDraw;
|
||
end
|
||
else
|
||
Number:=0;
|
||
if ((AState and sfActive)<>0) and (((OldState xor State) and sfActive)<>0) then
|
||
UpdateCommands;
|
||
end;
|
||
|
||
procedure TFPWindow.UpdateCommands;
|
||
begin
|
||
end;
|
||
|
||
procedure TFPWindow.Update;
|
||
begin
|
||
ReDraw;
|
||
end;
|
||
|
||
procedure TFPWindow.SelectInDebugSession;
|
||
var
|
||
F,PrevCurrent : PView;
|
||
begin
|
||
DeskTop^.Lock;
|
||
PrevCurrent:=Desktop^.Current;
|
||
F:=PrevCurrent;
|
||
While assigned(F) and
|
||
((F^.HelpCtx = hcGDBWindow) or
|
||
(F^.HelpCtx = hcdisassemblyWindow) or
|
||
(F^.HelpCtx = hcWatchesWindow) or
|
||
(F^.HelpCtx = hcStackWindow) or
|
||
(F^.HelpCtx = hcRegistersWindow) or
|
||
(F^.HelpCtx = hcVectorRegisters) or
|
||
(F^.HelpCtx = hcFPURegisters)) do
|
||
F:=F^.NextView;
|
||
if F<>@Self then
|
||
Select;
|
||
if PrevCurrent<>F then
|
||
Begin
|
||
Desktop^.InsertBefore(@self,F);
|
||
PrevCurrent^.Select;
|
||
End;
|
||
DeskTop^.Unlock;
|
||
end;
|
||
|
||
procedure TFPWindow.HandleEvent(var Event: TEvent);
|
||
begin
|
||
case Event.What of
|
||
evBroadcast :
|
||
case Event.Command of
|
||
cmUpdate :
|
||
Update;
|
||
cmSearchWindow+1..cmSearchWindow+99 :
|
||
if (Event.Command-cmSearchWindow=Number) then
|
||
ClearEvent(Event);
|
||
end;
|
||
end;
|
||
inherited HandleEvent(Event);
|
||
end;
|
||
|
||
|
||
constructor TFPWindow.Load(var S: TStream);
|
||
begin
|
||
inherited Load(S);
|
||
S.Read(AutoNumber,SizeOf(AutoNumber));
|
||
end;
|
||
|
||
procedure TFPWindow.Store(var S: TStream);
|
||
begin
|
||
inherited Store(S);
|
||
S.Write(AutoNumber,SizeOf(AutoNumber));
|
||
end;
|
||
|
||
function TFPHelpViewer.GetLocalMenu: PMenu;
|
||
var M: PMenu;
|
||
begin
|
||
M:=NewMenu(
|
||
{$ifdef DEBUG}
|
||
NewItem(menu_hlplocal_debug,'',kbNoKey,cmHelpDebug,hcHelpDebug,
|
||
{$endif DEBUG}
|
||
NewItem(menu_hlplocal_contents,'',kbNoKey,cmHelpContents,hcHelpContents,
|
||
NewItem(menu_hlplocal_index,menu_key_hlplocal_index,kbShiftF1,cmHelpIndex,hcHelpIndex,
|
||
NewItem(menu_hlplocal_topicsearch,menu_key_hlplocal_topicsearch,kbCtrlF1,cmHelpTopicSearch,hcHelpTopicSearch,
|
||
NewItem(menu_hlplocal_prevtopic,menu_key_hlplocal_prevtopic,kbAltF1,cmHelpPrevTopic,hcHelpPrevTopic,
|
||
NewLine(
|
||
NewItem(menu_hlplocal_copy,menu_key_hlplocal_copy,copy_key,cmCopy,hcCopy,
|
||
nil)))))))
|
||
{$ifdef DEBUG}
|
||
)
|
||
{$endif DEBUG}
|
||
;
|
||
GetLocalMenu:=M;
|
||
end;
|
||
|
||
function TFPHelpViewer.GetCommandTarget: PView;
|
||
begin
|
||
GetCommandTarget:=Application;
|
||
end;
|
||
|
||
constructor TFPHelpWindow.Init(var Bounds: TRect; ATitle: TTitleStr; ASourceFileID: word;
|
||
AContext: THelpCtx; ANumber: Integer);
|
||
begin
|
||
inherited Init(Bounds,ATitle,ASourceFileID,AContext,ANumber);
|
||
HelpCtx:=hcHelpWindow;
|
||
HideOnClose:=true;
|
||
end;
|
||
|
||
destructor TFPHelpWindow.Done;
|
||
begin
|
||
if HelpWindow=@Self then
|
||
HelpWindow:=nil;
|
||
Inherited Done;
|
||
end;
|
||
|
||
procedure TFPHelpWindow.InitHelpView;
|
||
var R: TRect;
|
||
begin
|
||
GetExtent(R); R.Grow(-1,-1);
|
||
HelpView:=New(PFPHelpViewer, Init(R, HSB, VSB));
|
||
HelpView^.GrowMode:=gfGrowHiX+gfGrowHiY;
|
||
end;
|
||
|
||
procedure TFPHelpWindow.Show;
|
||
begin
|
||
inherited Show;
|
||
if GetState(sfVisible) and (Number=0) then
|
||
begin
|
||
Number:=SearchFreeWindowNo;
|
||
ReDraw;
|
||
end;
|
||
end;
|
||
|
||
procedure TFPHelpWindow.Hide;
|
||
begin
|
||
inherited Hide;
|
||
if GetState(sfVisible)=false then
|
||
Number:=0;
|
||
end;
|
||
|
||
procedure TFPHelpWindow.HandleEvent(var Event: TEvent);
|
||
begin
|
||
case Event.What of
|
||
evBroadcast :
|
||
case Event.Command of
|
||
cmUpdate :
|
||
ReDraw;
|
||
cmSearchWindow+1..cmSearchWindow+99 :
|
||
if (Event.Command-cmSearchWindow=Number) then
|
||
ClearEvent(Event);
|
||
end;
|
||
end;
|
||
inherited HandleEvent(Event);
|
||
end;
|
||
|
||
function TFPHelpWindow.GetPalette: PPalette;
|
||
const P: string[length(CIDEHelpDialog)] = CIDEHelpDialog;
|
||
begin
|
||
GetPalette:=@P;
|
||
end;
|
||
|
||
constructor TFPHelpWindow.Load(var S: TStream);
|
||
begin
|
||
Abstract;
|
||
end;
|
||
|
||
procedure TFPHelpWindow.Store(var S: TStream);
|
||
begin
|
||
Abstract;
|
||
end;
|
||
|
||
constructor TSourceWindow.Init(var Bounds: TRect; AFileName: string);
|
||
var HSB,VSB: PScrollBar;
|
||
R: TRect;
|
||
PA : Array[1..2] of pointer;
|
||
LoadFile: boolean;
|
||
begin
|
||
inherited Init(Bounds,AFileName,{SearchFreeWindowNo}0);
|
||
AutoNumber:=true;
|
||
Options:=Options or ofTileAble;
|
||
GetExtent(R); R.A.Y:=R.B.Y-1; R.Grow(-1,0); R.A.X:=14;
|
||
New(HSB, Init(R)); HSB^.GrowMode:=gfGrowLoY+gfGrowHiX+gfGrowHiY; Insert(HSB);
|
||
GetExtent(R); R.A.X:=R.B.X-1; R.Grow(0,-1);
|
||
New(VSB, Init(R)); VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY; Insert(VSB);
|
||
GetExtent(R); R.A.X:=3; R.B.X:=14; R.A.Y:=R.B.Y-1;
|
||
New(Indicator, Init(R));
|
||
Indicator^.GrowMode:=gfGrowLoY+gfGrowHiY;
|
||
Insert(Indicator);
|
||
GetExtent(R); R.Grow(-1,-1);
|
||
LoadFile:=(AFileName<>'') and (AFileName<>'*');
|
||
if (AFileName='') then
|
||
begin
|
||
Inc(GlobalNoNameCount);
|
||
NoNameCount:=GlobalNoNameCount;
|
||
end
|
||
else
|
||
NoNameCount:=-1;
|
||
if AFileName='*' then
|
||
AFileName:='';
|
||
New(Editor, Init(R, HSB, VSB, Indicator,AFileName));
|
||
Editor^.GrowMode:=gfGrowHiX+gfGrowHiY;
|
||
if LoadFile then
|
||
begin
|
||
if Editor^.LoadFile=false then
|
||
ErrorBox(FormatStrStr(msg_errorreadingfile,AFileName),nil)
|
||
{ warn if modified, but not if modified in another
|
||
already open window PM }
|
||
else if Editor^.GetModified and (Editor^.Core^.GetBindingCount=1) then
|
||
begin
|
||
PA[1]:=@AFileName;
|
||
Ptrint(PA[2]):={Editor^.ChangedLine}-1;
|
||
EditorDialog(edChangedOnloading,@PA);
|
||
end;
|
||
end;
|
||
Insert(Editor);
|
||
{$ifndef NODEBUG}
|
||
If assigned(BreakpointsCollection) then
|
||
BreakpointsCollection^.ShowBreakpoints(@Self);
|
||
{$endif NODEBUG}
|
||
UpdateTitle;
|
||
end;
|
||
|
||
procedure TSourceWindow.UpdateTitle;
|
||
var Name: string;
|
||
Count: sw_integer;
|
||
begin
|
||
if Editor^.FileName<>'' then
|
||
begin
|
||
Name:=SmartPath(Editor^.FileName);
|
||
Count:=Editor^.Core^.GetBindingCount;
|
||
if Count>1 then
|
||
begin
|
||
Name:=Name+':'+IntToStr(Editor^.Core^.GetBindingIndex(Editor)+1);
|
||
end;
|
||
SetTitle(Name);
|
||
end
|
||
else if NoNameCount>=0 then
|
||
begin
|
||
SetTitle('noname'+IntToStrZ(NonameCount,2)+'.pas');
|
||
end;
|
||
end;
|
||
|
||
function TSourceWindow.GetTitle(MaxSize: sw_Integer): TTitleStr;
|
||
begin
|
||
GetTitle:=OptimizePath(inherited GetTitle(255),MaxSize);
|
||
end;
|
||
|
||
procedure TSourceWindow.SetTitle(ATitle: string);
|
||
begin
|
||
if Title<>nil then DisposeStr(Title);
|
||
Title:=NewStr(ATitle);
|
||
Frame^.DrawView;
|
||
end;
|
||
|
||
procedure TSourceWindow.HandleEvent(var Event: TEvent);
|
||
var DontClear: boolean;
|
||
begin
|
||
case Event.What of
|
||
evBroadcast :
|
||
case Event.Command of
|
||
cmUpdate :
|
||
Update;
|
||
cmUpdateTitle :
|
||
UpdateTitle;
|
||
cmSearchWindow :
|
||
if @Self<>ClipboardWindow then
|
||
ClearEvent(Event);
|
||
end;
|
||
evCommand :
|
||
begin
|
||
DontClear:=false;
|
||
case Event.Command of
|
||
cmHide :
|
||
Hide;
|
||
cmSave :
|
||
if Editor^.IsClipboard=false then
|
||
if (Editor^.FileName='') then
|
||
Editor^.SaveAs
|
||
else
|
||
Editor^.Save;
|
||
cmSaveAs :
|
||
if Editor^.IsClipboard=false then
|
||
Editor^.SaveAs;
|
||
else DontClear:=true;
|
||
end;
|
||
if DontClear=false then ClearEvent(Event);
|
||
end;
|
||
end;
|
||
inherited HandleEvent(Event);
|
||
end;
|
||
|
||
procedure TSourceWindow.UpdateCommands;
|
||
var Active: boolean;
|
||
begin
|
||
Active:=GetState(sfActive);
|
||
if Editor^.IsClipboard=false then
|
||
begin
|
||
SetCmdState(SourceCmds+CompileCmds,Active);
|
||
SetCmdState(EditorCmds,Active);
|
||
end;
|
||
SetCmdState(ToClipCmds+FromClipCmds+NulClipCmds+UndoCmd+RedoCmd,Active);
|
||
Message(Application,evBroadcast,cmCommandSetChanged,nil);
|
||
end;
|
||
|
||
procedure TSourceWindow.Update;
|
||
begin
|
||
ReDraw;
|
||
end;
|
||
|
||
|
||
function TSourceWindow.GetPalette: PPalette;
|
||
const P: string[length(CSourceWindow)] = CSourceWindow;
|
||
begin
|
||
GetPalette:=@P;
|
||
end;
|
||
|
||
constructor TSourceWindow.Load(var S: TStream);
|
||
begin
|
||
Title:=S.ReadStr;
|
||
PushStatus(FormatStrStr(msg_loadingfile,GetStr(Title)));
|
||
inherited Load(S);
|
||
GetSubViewPtr(S,Indicator);
|
||
GetSubViewPtr(S,Editor);
|
||
{$ifndef NODEBUG}
|
||
If assigned(BreakpointsCollection) then
|
||
BreakpointsCollection^.ShowBreakpoints(@Self);
|
||
{$endif NODEBUG}
|
||
PopStatus;
|
||
end;
|
||
|
||
procedure TSourceWindow.Store(var S: TStream);
|
||
begin
|
||
S.WriteStr(Title);
|
||
PushStatus(FormatStrStr(msg_storingfile,GetStr(Title)));
|
||
inherited Store(S);
|
||
|
||
PutSubViewPtr(S,Indicator);
|
||
PutSubViewPtr(S,Editor);
|
||
PopStatus;
|
||
end;
|
||
|
||
|
||
procedure TSourceWindow.Close;
|
||
begin
|
||
inherited Close;
|
||
end;
|
||
|
||
destructor TSourceWindow.Done;
|
||
begin
|
||
PushStatus(FormatStrStr(msg_closingfile,GetStr(Title)));
|
||
if not IDEApp.IsClosing then
|
||
Message(Application,evBroadcast,cmSourceWndClosing,@Self);
|
||
inherited Done;
|
||
IDEApp.SourceWindowClosed;
|
||
{ if not IDEApp.IsClosing then
|
||
Message(Application,evBroadcast,cmUpdate,@Self);}
|
||
PopStatus;
|
||
end;
|
||
|
||
|
||
{$ifndef NODEBUG}
|
||
|
||
function TGDBSourceEditor.Valid(Command: Word): Boolean;
|
||
var OK: boolean;
|
||
begin
|
||
OK:=TCodeEditor.Valid(Command);
|
||
{ do NOT ask for save !!
|
||
if OK and ((Command=cmClose) or (Command=cmQuit)) then
|
||
if IsClipboard=false then
|
||
OK:=SaveAsk; }
|
||
Valid:=OK;
|
||
end;
|
||
|
||
procedure TGDBSourceEditor.AddLine(const S: string);
|
||
begin
|
||
if Silent or (IgnoreStringAtEnd and (S=LastCommand)) then exit;
|
||
inherited AddLine(S);
|
||
LimitsChanged;
|
||
end;
|
||
|
||
procedure TGDBSourceEditor.AddErrorLine(const S: string);
|
||
begin
|
||
if Silent then exit;
|
||
inherited AddLine(S);
|
||
{ display like breakpoints in red }
|
||
SetLineFlagState(GetLineCount-1,lfBreakpoint,true);
|
||
LimitsChanged;
|
||
end;
|
||
|
||
const
|
||
GDBReservedCount = 6;
|
||
GDBReservedLongest = 3;
|
||
GDBReserved : array[1..GDBReservedCount] of String[GDBReservedLongest] =
|
||
('gdb','b','n','s','f','bt');
|
||
|
||
function IsGDBReservedWord(const S : string) : boolean;
|
||
var
|
||
i : longint;
|
||
begin
|
||
for i:=1 to GDBReservedCount do
|
||
if (S=GDBReserved[i]) then
|
||
begin
|
||
IsGDBReservedWord:=true;
|
||
exit;
|
||
end;
|
||
IsGDBReservedWord:=false;
|
||
end;
|
||
|
||
function TGDBSourceEditor.IsReservedWord(const S: string): boolean;
|
||
begin
|
||
IsReservedWord:=IsGDBReservedWord(S);
|
||
end;
|
||
|
||
function TGDBSourceEditor.InsertNewLine: Sw_integer;
|
||
Var
|
||
S : string;
|
||
CommandCalled : boolean;
|
||
|
||
begin
|
||
if IsReadOnly then begin InsertNewLine:=-1; Exit; end;
|
||
if CurPos.Y<GetLineCount then S:=GetDisplayText(CurPos.Y) else S:='';
|
||
s:=Copy(S,1,CurPos.X);
|
||
CommandCalled:=false;
|
||
if Pos(GDBPrompt,S)=1 then
|
||
Delete(S,1,length(GDBPrompt));
|
||
{$ifndef NODEBUG}
|
||
if assigned(Debugger) then
|
||
if S<>'' then
|
||
begin
|
||
LastCommand:=S;
|
||
{ should be true only if we are at the end ! }
|
||
IgnoreStringAtEnd:=(CurPos.Y=GetLineCount-1) and
|
||
(CurPos.X>=length(RTrim(GetDisplayText(GetLineCount-1))));
|
||
Debugger^.Command(S);
|
||
CommandCalled:=true;
|
||
IgnoreStringAtEnd:=false;
|
||
end
|
||
else if AutoRepeat and (CurPos.Y=GetLineCount-1) then
|
||
begin
|
||
Debugger^.Command(LastCommand);
|
||
CommandCalled:=true;
|
||
end;
|
||
{$endif NODEBUG}
|
||
InsertNewLine:=inherited InsertNewLine;
|
||
If CommandCalled then
|
||
InsertText(GDBPrompt);
|
||
end;
|
||
|
||
|
||
constructor TGDBWindow.Init(var Bounds: TRect);
|
||
var HSB,VSB: PScrollBar;
|
||
R: TRect;
|
||
begin
|
||
inherited Init(Bounds,dialog_gdbwindow,0);
|
||
Options:=Options or ofTileAble;
|
||
AutoNumber:=true;
|
||
HelpCtx:=hcGDBWindow;
|
||
GetExtent(R); R.A.Y:=R.B.Y-1; R.Grow(-1,0); R.A.X:=14;
|
||
New(HSB, Init(R)); HSB^.GrowMode:=gfGrowLoY+gfGrowHiX+gfGrowHiY; Insert(HSB);
|
||
GetExtent(R); R.A.X:=R.B.X-1; R.Grow(0,-1);
|
||
New(VSB, Init(R)); VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY; Insert(VSB);
|
||
GetExtent(R); R.A.X:=3; R.B.X:=14; R.A.Y:=R.B.Y-1;
|
||
New(Indicator, Init(R));
|
||
Indicator^.GrowMode:=gfGrowLoY+gfGrowHiY;
|
||
Insert(Indicator);
|
||
GetExtent(R); R.Grow(-1,-1);
|
||
New(Editor, Init(R, HSB, VSB, Indicator, GDBOutputFile));
|
||
Editor^.GrowMode:=gfGrowHiX+gfGrowHiY;
|
||
Editor^.SetFlags(efInsertMode+efSyntaxHighlight+efNoIndent+efExpandAllTabs);
|
||
if ExistsFile(GDBOutputFile) then
|
||
begin
|
||
if Editor^.LoadFile=false then
|
||
ErrorBox(FormatStrStr(msg_errorreadingfile,GDBOutputFile),nil);
|
||
end
|
||
else
|
||
{ Empty files are buggy !! }
|
||
Editor^.AddLine('');
|
||
Insert(Editor);
|
||
{$ifndef NODEBUG}
|
||
if assigned(Debugger) then
|
||
Debugger^.SetWidth(Size.X-1);
|
||
{$endif NODEBUG}
|
||
Editor^.silent:=false;
|
||
Editor^.AutoRepeat:=true;
|
||
Editor^.InsertText(GDBPrompt);
|
||
end;
|
||
|
||
procedure TGDBWindow.HandleEvent(var Event: TEvent);
|
||
var DontClear: boolean;
|
||
begin
|
||
case Event.What of
|
||
evCommand :
|
||
begin
|
||
DontClear:=false;
|
||
case Event.Command of
|
||
cmSaveAs :
|
||
Editor^.SaveAs;
|
||
else DontClear:=true;
|
||
end;
|
||
if DontClear=false then ClearEvent(Event);
|
||
end;
|
||
end;
|
||
inherited HandleEvent(Event);
|
||
end;
|
||
|
||
destructor TGDBWindow.Done;
|
||
begin
|
||
if @Self=GDBWindow then
|
||
GDBWindow:=nil;
|
||
inherited Done;
|
||
end;
|
||
|
||
constructor TGDBWindow.Load(var S: TStream);
|
||
begin
|
||
inherited Load(S);
|
||
GetSubViewPtr(S,Indicator);
|
||
GetSubViewPtr(S,Editor);
|
||
GDBWindow:=@self;
|
||
end;
|
||
|
||
procedure TGDBWindow.Store(var S: TStream);
|
||
begin
|
||
inherited Store(S);
|
||
PutSubViewPtr(S,Indicator);
|
||
PutSubViewPtr(S,Editor);
|
||
end;
|
||
|
||
function TGDBWindow.GetPalette: PPalette;
|
||
const P: string[length(CSourceWindow)] = CSourceWindow;
|
||
begin
|
||
GetPalette:=@P;
|
||
end;
|
||
|
||
procedure TGDBWindow.WriteOutputText(Buf : pchar);
|
||
begin
|
||
{selected normal color ?}
|
||
WriteText(Buf,false);
|
||
end;
|
||
|
||
procedure TGDBWindow.WriteErrorText(Buf : pchar);
|
||
begin
|
||
{selected normal color ?}
|
||
WriteText(Buf,true);
|
||
end;
|
||
|
||
procedure TGDBWindow.WriteString(Const S : string);
|
||
begin
|
||
Editor^.AddLine(S);
|
||
end;
|
||
|
||
procedure TGDBWindow.WriteErrorString(Const S : string);
|
||
begin
|
||
Editor^.AddErrorLine(S);
|
||
end;
|
||
|
||
procedure TGDBWindow.WriteText(Buf : pchar;IsError : boolean);
|
||
var p,pe : pchar;
|
||
s : string;
|
||
begin
|
||
p:=buf;
|
||
DeskTop^.Lock;
|
||
While assigned(p) and (p^<>#0) do
|
||
begin
|
||
pe:=strscan(p,#10);
|
||
if pe<>nil then
|
||
pe^:=#0;
|
||
s:=strpas(p);
|
||
If IsError then
|
||
Editor^.AddErrorLine(S)
|
||
else
|
||
Editor^.AddLine(S);
|
||
{ restore for dispose }
|
||
if pe<>nil then
|
||
pe^:=#10;
|
||
if pe=nil then
|
||
p:=nil
|
||
else
|
||
begin
|
||
if pe-p > High(s) then
|
||
p:=p+High(s)-1
|
||
else
|
||
begin
|
||
p:=pe;
|
||
inc(p);
|
||
end;
|
||
end;
|
||
end;
|
||
DeskTop^.Unlock;
|
||
Editor^.Draw;
|
||
end;
|
||
|
||
procedure TGDBWindow.UpdateCommands;
|
||
var Active: boolean;
|
||
begin
|
||
Active:=GetState(sfActive);
|
||
SetCmdState([cmSaveAs,cmHide,cmRun],Active);
|
||
SetCmdState(EditorCmds,Active);
|
||
SetCmdState(ToClipCmds+FromClipCmds+NulClipCmds+UndoCmd+RedoCmd,Active);
|
||
Message(Application,evBroadcast,cmCommandSetChanged,nil);
|
||
end;
|
||
|
||
|
||
function TDisasLineCollection.At(Index: sw_Integer): PDisasLine;
|
||
begin
|
||
At := PDisasLine(Inherited At(Index));
|
||
end;
|
||
|
||
constructor TDisassemblyEditor.Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
|
||
PScrollBar; AIndicator: PIndicator;const AFileName: string);
|
||
begin
|
||
Inherited Init(Bounds,AHScrollBar,AVScrollBar,AIndicator,AFileName);
|
||
GrowMode:=gfGrowHiX+gfGrowHiY;
|
||
SetFlags(efInsertMode+efSyntaxHighlight+efNoIndent+efExpandAllTabs{+efHighlightRow});
|
||
New(DisasLines,Init(500,1000));
|
||
Core^.ChangeLinesTo(DisasLines);
|
||
{ do not allow to write into that window }
|
||
ReadOnly:=true;
|
||
AddLine('');
|
||
MinAddress:=0;
|
||
MaxAddress:=0;
|
||
CurL:=nil;
|
||
OwnsSource:=false;
|
||
Source:=nil;
|
||
end;
|
||
|
||
destructor TDisassemblyEditor.Done;
|
||
begin
|
||
ReleaseSource;
|
||
Inherited Done;
|
||
end;
|
||
|
||
procedure TDisassemblyEditor.ReleaseSource;
|
||
begin
|
||
if OwnsSource and assigned(source) then
|
||
begin
|
||
Desktop^.Delete(Source);
|
||
Dispose(Source,Done);
|
||
end;
|
||
OwnsSource:=false;
|
||
Source:=nil;
|
||
CurrentSource:='';
|
||
end;
|
||
|
||
procedure TDisassemblyEditor.AddSourceLine(const AFileName: string;line : longint);
|
||
var
|
||
S : String;
|
||
begin
|
||
if AFileName<>CurrentSource then
|
||
begin
|
||
ReleaseSource;
|
||
Source:=SearchOnDesktop(FileName,false);
|
||
if not assigned(Source) then
|
||
begin
|
||
Source:=ITryToOpenFile(nil,AFileName,0,line,false,false,true);
|
||
OwnsSource:=true;
|
||
end
|
||
else
|
||
OwnsSource:=false;
|
||
CurrentSource:=AFileName;
|
||
end;
|
||
if Assigned(Source) and (line>0) then
|
||
S:=Trim(Source^.Editor^.GetLineText(line-1))
|
||
else
|
||
S:='<source not found>';
|
||
CurrentLine:=Line;
|
||
inherited AddLine(AFileName+':'+IntToStr(line)+' '+S);
|
||
{ display differently }
|
||
SetLineFlagState(GetLineCount-1,lfSpecialRow,true);
|
||
LimitsChanged;
|
||
end;
|
||
|
||
procedure TDisassemblyEditor.AddAssemblyLine(const S: string;AAddress : cardinal);
|
||
var
|
||
PL : PDisasLine;
|
||
LI : PEditorLineInfo;
|
||
begin
|
||
if AAddress<>0 then
|
||
inherited AddLine('$'+hexstr(AAddress,sizeof(PtrUInt)*2)+S)
|
||
else
|
||
inherited AddLine(S);
|
||
PL:=DisasLines^.At(DisasLines^.count-1);
|
||
PL^.Address:=AAddress;
|
||
LI:=PL^.GetEditorInfo(@Self);
|
||
if AAddress<>0 then
|
||
LI^.BeginsWithAsm:=true;
|
||
LimitsChanged;
|
||
if ((AAddress<minaddress) or (minaddress=0)) and (AAddress<>0) then
|
||
MinAddress:=AAddress;
|
||
if (AAddress>maxaddress) or (maxaddress=0) then
|
||
MaxAddress:=AAddress;
|
||
end;
|
||
|
||
function TDisassemblyEditor.GetCurrentLine(address : cardinal) : PDisasLine;
|
||
|
||
function IsCorrectLine(PL : PDisasLine) : boolean;
|
||
begin
|
||
IsCorrectLine:=PL^.Address=Address;
|
||
end;
|
||
Var
|
||
PL : PDisasLine;
|
||
begin
|
||
PL:=DisasLines^.FirstThat(@IsCorrectLine);
|
||
if Assigned(PL) then
|
||
begin
|
||
if assigned(CurL) then
|
||
CurL^.SetFlagState(lfDebuggerRow,false);
|
||
SetCurPtr(0,DisasLines^.IndexOf(PL));
|
||
PL^.SetFlags(lfDebuggerRow);
|
||
CurL:=PL;
|
||
TrackCursor(do_not_centre);
|
||
end;
|
||
GetCurrentLine:=PL;
|
||
end;
|
||
|
||
{ PDisassemblyWindow = ^TDisassemblyWindow;
|
||
TDisassemblyWindow = object(TFPWindow)
|
||
Editor : PDisassemblyEditor;
|
||
Indicator : PIndicator; }
|
||
constructor TDisassemblyWindow.Init(var Bounds: TRect);
|
||
var HSB,VSB: PScrollBar;
|
||
R: TRect;
|
||
begin
|
||
inherited Init(Bounds,dialog_disaswindow,0);
|
||
Options:=Options or ofTileAble;
|
||
AutoNumber:=true;
|
||
HelpCtx:=hcDisassemblyWindow;
|
||
GetExtent(R); R.A.Y:=R.B.Y-1; R.Grow(-1,0); R.A.X:=14;
|
||
New(HSB, Init(R)); HSB^.GrowMode:=gfGrowLoY+gfGrowHiX+gfGrowHiY; Insert(HSB);
|
||
GetExtent(R); R.A.X:=R.B.X-1; R.Grow(0,-1);
|
||
New(VSB, Init(R)); VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY; Insert(VSB);
|
||
GetExtent(R); R.A.X:=3; R.B.X:=14; R.A.Y:=R.B.Y-1;
|
||
New(Indicator, Init(R));
|
||
Indicator^.GrowMode:=gfGrowLoY+gfGrowHiY;
|
||
Insert(Indicator);
|
||
GetExtent(R); R.Grow(-1,-1);
|
||
New(Editor, Init(R, HSB, VSB, nil, GDBOutputFile));
|
||
Insert(Editor);
|
||
DisassemblyWindow:=@Self;
|
||
end;
|
||
|
||
procedure TDisassemblyWindow.LoadFunction(Const FuncName : string);
|
||
var
|
||
p : pchar;
|
||
begin
|
||
{$ifndef NODEBUG}
|
||
If not assigned(Debugger) then Exit;
|
||
Debugger^.Command('set print sym on');
|
||
Debugger^.Command('set width 0xffffffff');
|
||
Debugger^.Command('disas '+FuncName);
|
||
p:=StrNew(Debugger^.GetOutput);
|
||
ProcessPChar(p);
|
||
if (Debugger^.IsRunning) and (FuncName='') then
|
||
Editor^.GetCurrentLine(Debugger^.current_pc);
|
||
{$endif NODEBUG}
|
||
end;
|
||
|
||
procedure TDisassemblyWindow.LoadAddress(Addr : cardinal);
|
||
var
|
||
p : pchar;
|
||
begin
|
||
{$ifndef NODEBUG}
|
||
If not assigned(Debugger) then Exit;
|
||
Debugger^.Command('set print sym on');
|
||
Debugger^.Command('set width 0xffffffff');
|
||
Debugger^.Command('disas 0x'+HexStr(Addr,8));
|
||
p:=StrNew(Debugger^.GetOutput);
|
||
ProcessPChar(p);
|
||
if Debugger^.IsRunning and
|
||
(Debugger^.current_pc>=Editor^.MinAddress) and
|
||
(Debugger^.current_pc<=Editor^.MaxAddress) then
|
||
Editor^.GetCurrentLine(Debugger^.current_pc);
|
||
{$endif NODEBUG}
|
||
end;
|
||
|
||
|
||
function TDisassemblyWindow.ProcessPChar(p : pchar) : boolean;
|
||
var
|
||
p1: pchar;
|
||
pline : pchar;
|
||
pos1, pos2, CurLine, PrevLine : longint;
|
||
CurAddr : cardinal;
|
||
err : word;
|
||
curaddress, cursymofs, CurFile,
|
||
PrevFile, line : string;
|
||
begin
|
||
ProcessPChar:=true;
|
||
Lock;
|
||
Editor^.DisasLines^.FreeAll;
|
||
Editor^.SetFlags(Editor^.GetFlags or efSyntaxHighlight or efKeepLineAttr);
|
||
|
||
Editor^.MinAddress:=0;
|
||
Editor^.MaxAddress:=0;
|
||
Editor^.CurL:=nil;
|
||
p1:=p;
|
||
PrevFile:='';
|
||
PrevLine:=0;
|
||
while assigned(p) do
|
||
begin
|
||
pline:=strscan(p,#10);
|
||
if assigned(pline) then
|
||
pline^:=#0;
|
||
line:=strpas(p);
|
||
CurAddr:=0;
|
||
if assigned(pline) then
|
||
begin
|
||
pline^:=#10;
|
||
p:=pline+1;
|
||
end
|
||
else
|
||
p:=nil;
|
||
{ now process the line }
|
||
{ line is hexaddr <symbol+sym_offset at filename:line> assembly }
|
||
pos1:=pos('<',line);
|
||
if pos1>0 then
|
||
begin
|
||
curaddress:=copy(line,1,pos1-1);
|
||
if copy(curaddress,1,2)='0x' then
|
||
curaddress:='$'+copy(curaddress,3,length(curaddress)-2);
|
||
val(curaddress,CurAddr,err);
|
||
if err>0 then
|
||
val(copy(curaddress,1,err-1),CurAddr,err);
|
||
system.delete(line,1,pos1);
|
||
end;
|
||
pos1:=pos(' at ',line);
|
||
pos2:=pos('>',line);
|
||
if (pos1>0) and (pos1 < pos2) then
|
||
begin
|
||
cursymofs:=copy(line,1,pos1-1);
|
||
CurFile:=copy(line,pos1+4,pos2-pos1-4);
|
||
pos1:=pos(':',CurFile);
|
||
if pos1>0 then
|
||
begin
|
||
val(copy(CurFile,pos1+1,high(CurFile)),CurLine,err);
|
||
system.delete(CurFile,pos1,high(CurFile));
|
||
end
|
||
else
|
||
CurLine:=0;
|
||
system.delete(line,1,pos2);
|
||
end
|
||
else { no ' at ' found before '>' }
|
||
begin
|
||
cursymofs:=copy(line,1,pos2-1);
|
||
CurFile:='';
|
||
system.delete(line,1,pos2);
|
||
end;
|
||
if (CurFile<>'') and ((CurFile<>PrevFile) or (CurLine<>PrevLine)) then
|
||
begin
|
||
WriteSourceString(CurFile,CurLine);
|
||
PrevLine:=CurLine;
|
||
PrevFile:=CurFile;
|
||
end;
|
||
WriteDisassemblyString(line,curaddr);
|
||
end;
|
||
StrDispose(p1);
|
||
Editor^.ReleaseSource;
|
||
Editor^.UpdateAttrs(0,attrForceFull);
|
||
If assigned(BreakpointsCollection) then
|
||
BreakpointsCollection^.ShowBreakpoints(@Self);
|
||
Unlock;
|
||
ReDraw;
|
||
end;
|
||
|
||
procedure TDisassemblyWindow.HandleEvent(var Event: TEvent);
|
||
begin
|
||
inherited HandleEvent(Event);
|
||
end;
|
||
|
||
procedure TDisassemblyWindow.WriteSourceString(Const S : string;line : longint);
|
||
begin
|
||
Editor^.AddSourceLine(S,line);
|
||
end;
|
||
|
||
procedure TDisassemblyWindow.WriteDisassemblyString(Const S : string;address : cardinal);
|
||
begin
|
||
Editor^.AddAssemblyLine(S,address);
|
||
end;
|
||
|
||
procedure TDisassemblyWindow.SetCurAddress(address : cardinal);
|
||
begin
|
||
if (address<Editor^.MinAddress) or (address>Editor^.MaxAddress) then
|
||
LoadAddress(address);
|
||
Editor^.GetCurrentLine(address);
|
||
end;
|
||
|
||
procedure TDisassemblyWindow.UpdateCommands;
|
||
var Active: boolean;
|
||
begin
|
||
Active:=GetState(sfActive);
|
||
SetCmdState(SourceCmds+CompileCmds,Active);
|
||
SetCmdState(EditorCmds,Active);
|
||
SetCmdState(ToClipCmds+FromClipCmds+NulClipCmds+UndoCmd+RedoCmd,false);
|
||
Message(Application,evBroadcast,cmCommandSetChanged,nil);
|
||
end;
|
||
|
||
|
||
function TDisassemblyWindow.GetPalette: PPalette;
|
||
const P: string[length(CSourceWindow)] = CSourceWindow;
|
||
begin
|
||
GetPalette:=@P;
|
||
end;
|
||
|
||
destructor TDisassemblyWindow.Done;
|
||
begin
|
||
if @Self=DisassemblyWindow then
|
||
DisassemblyWindow:=nil;
|
||
inherited Done;
|
||
end;
|
||
{$endif NODEBUG}
|
||
|
||
|
||
|
||
constructor TClipboardWindow.Init;
|
||
var R: TRect;
|
||
HSB,VSB: PScrollBar;
|
||
begin
|
||
Desktop^.GetExtent(R);
|
||
inherited Init(R, '*');
|
||
SetTitle(dialog_clipboard);
|
||
HelpCtx:=hcClipboardWindow;
|
||
Number:=wnNoNumber;
|
||
AutoNumber:=true;
|
||
|
||
GetExtent(R); R.A.Y:=R.B.Y-1; R.Grow(-1,0); R.A.X:=14;
|
||
New(HSB, Init(R)); HSB^.GrowMode:=gfGrowLoY+gfGrowHiX+gfGrowHiY; Insert(HSB);
|
||
GetExtent(R); R.A.X:=R.B.X-1; R.Grow(0,-1);
|
||
New(VSB, Init(R)); VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY; Insert(VSB);
|
||
GetExtent(R); R.A.X:=3; R.B.X:=14; R.A.Y:=R.B.Y-1;
|
||
New(Indicator, Init(R));
|
||
Indicator^.GrowMode:=gfGrowLoY+gfGrowHiY;
|
||
Insert(Indicator);
|
||
GetExtent(R); R.Grow(-1,-1);
|
||
New(Editor, Init(R, HSB, VSB, Indicator, ''));
|
||
Editor^.GrowMode:=gfGrowHiX+gfGrowHiY;
|
||
Insert(Editor);
|
||
|
||
Editor^.SetFlags(Editor^.GetFlags or efUseTabCharacters);
|
||
Hide;
|
||
|
||
Clipboard:=Editor;
|
||
end;
|
||
|
||
procedure TClipboardWindow.Close;
|
||
begin
|
||
Hide;
|
||
end;
|
||
|
||
constructor TClipboardWindow.Load(var S: TStream);
|
||
begin
|
||
inherited Load(S);
|
||
|
||
Clipboard:=Editor;
|
||
end;
|
||
|
||
procedure TClipboardWindow.Store(var S: TStream);
|
||
begin
|
||
inherited Store(S);
|
||
end;
|
||
|
||
destructor TClipboardWindow.Done;
|
||
begin
|
||
inherited Done;
|
||
Clipboard:=nil;
|
||
ClipboardWindow:=nil;
|
||
end;
|
||
|
||
|
||
constructor TMessageListBox.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
|
||
begin
|
||
inherited Init(Bounds,1,AHScrollBar, AVScrollBar);
|
||
GrowMode:=gfGrowHiX+gfGrowHiY;
|
||
New(ModuleNames, Init(50,100));
|
||
NoSelection:=true;
|
||
end;
|
||
|
||
|
||
function TMessageListBox.GetLocalMenu: PMenu;
|
||
var M: PMenu;
|
||
begin
|
||
if (Owner<>nil) and (Owner^.GetState(sfModal)) then M:=nil else
|
||
M:=NewMenu(
|
||
NewItem(menu_msglocal_clear,'',kbNoKey,cmMsgClear,hcMsgClear,
|
||
NewLine(
|
||
NewItem(menu_msglocal_gotosource,'',kbNoKey,cmMsgGotoSource,hcMsgGotoSource,
|
||
NewItem(menu_msglocal_tracksource,'',kbNoKey,cmMsgTrackSource,hcMsgTrackSource,
|
||
NewLine(
|
||
NewItem(menu_msglocal_saveas,'',kbNoKey,cmSaveAs,hcSaveAs,
|
||
nil)))))));
|
||
GetLocalMenu:=M;
|
||
end;
|
||
|
||
procedure TMessageListBox.SetState(AState: Word; Enable: Boolean);
|
||
var OldState: word;
|
||
begin
|
||
OldState:=State;
|
||
inherited SetState(AState,Enable);
|
||
if ((AState and sfActive)<>0) and (((OldState xor State) and sfActive)<>0) then
|
||
SetCmdState([cmSaveAs],Enable);
|
||
end;
|
||
|
||
|
||
procedure TMessageListBox.HandleEvent(var Event: TEvent);
|
||
var DontClear: boolean;
|
||
begin
|
||
case Event.What of
|
||
evKeyDown :
|
||
begin
|
||
DontClear:=false;
|
||
case Event.KeyCode of
|
||
kbEnter :
|
||
begin
|
||
Message(@Self,evCommand,cmMsgGotoSource,nil);
|
||
ClearEvent(Event);
|
||
exit;
|
||
end;
|
||
else
|
||
DontClear:=true;
|
||
end;
|
||
if not DontClear then
|
||
ClearEvent(Event);
|
||
end;
|
||
evBroadcast :
|
||
case Event.Command of
|
||
cmListItemSelected :
|
||
if Event.InfoPtr=@Self then
|
||
Message(@Self,evCommand,cmMsgTrackSource,nil);
|
||
end;
|
||
evCommand :
|
||
begin
|
||
DontClear:=false;
|
||
case Event.Command of
|
||
cmMsgGotoSource :
|
||
if Range>0 then
|
||
begin
|
||
GotoSource;
|
||
ClearEvent(Event);
|
||
exit;
|
||
end;
|
||
cmMsgTrackSource :
|
||
if Range>0 then
|
||
TrackSource;
|
||
cmMsgClear :
|
||
Clear;
|
||
cmSaveAs :
|
||
SaveAs;
|
||
else
|
||
DontClear:=true;
|
||
end;
|
||
if not DontClear then
|
||
ClearEvent(Event);
|
||
end;
|
||
end;
|
||
inherited HandleEvent(Event);
|
||
end;
|
||
|
||
procedure TMessageListBox.AddItem(P: PMessageItem);
|
||
var W : integer;
|
||
begin
|
||
if List=nil then New(List, Init(500,500));
|
||
W:=length(P^.GetText(255));
|
||
if W>MaxWidth then
|
||
begin
|
||
MaxWidth:=W;
|
||
if HScrollBar<>nil then
|
||
HScrollBar^.SetRange(0,MaxWidth);
|
||
end;
|
||
List^.Insert(P);
|
||
SetRange(List^.Count);
|
||
if Focused=List^.Count-1-1 then
|
||
FocusItem(List^.Count-1);
|
||
DrawView;
|
||
end;
|
||
|
||
function TMessageListBox.AddModuleName(const Name: string): PString;
|
||
var P: PString;
|
||
begin
|
||
if ModuleNames<>nil then
|
||
P:=ModuleNames^.Add(Name)
|
||
else
|
||
P:=nil;
|
||
AddModuleName:=P;
|
||
end;
|
||
|
||
function TMessageListBox.GetText(Item,MaxLen: Sw_Integer): String;
|
||
var P: PMessageItem;
|
||
S: string;
|
||
begin
|
||
P:=List^.At(Item);
|
||
S:=P^.GetText(MaxLen);
|
||
GetText:=copy(S,1,MaxLen);
|
||
end;
|
||
|
||
procedure TMessageListBox.Clear;
|
||
begin
|
||
if assigned(List) then
|
||
Dispose(List, Done);
|
||
List:=nil;
|
||
MaxWidth:=0;
|
||
if assigned(ModuleNames) then
|
||
ModuleNames^.FreeAll;
|
||
SetRange(0); DrawView;
|
||
Message(Application,evBroadcast,cmClearLineHighlights,@Self);
|
||
end;
|
||
|
||
procedure TMessageListBox.TrackSource;
|
||
var W: PSourceWindow;
|
||
P: PMessageItem;
|
||
R: TRect;
|
||
Row,Col: sw_integer;
|
||
Found : boolean;
|
||
begin
|
||
Message(Application,evBroadcast,cmClearLineHighlights,@Self);
|
||
if Range=0 then Exit;
|
||
P:=List^.At(Focused);
|
||
if P^.Row=0 then Exit;
|
||
Desktop^.Lock;
|
||
GetNextEditorBounds(R);
|
||
R.B.Y:=Owner^.Origin.Y;
|
||
if P^.Row>0 then Row:=P^.Row-1 else Row:=0;
|
||
if P^.Col>0 then Col:=P^.Col-1 else Col:=0;
|
||
W:=EditorWindowFile(P^.GetModuleName);
|
||
if assigned(W) then
|
||
begin
|
||
W^.GetExtent(R);
|
||
R.B.Y:=Owner^.Origin.Y;
|
||
W^.ChangeBounds(R);
|
||
W^.Editor^.SetCurPtr(Col,Row);
|
||
end
|
||
else
|
||
W:=TryToOpenFile(@R,P^.GetModuleName,Col,Row,true);
|
||
{ Try to find it by browsing }
|
||
if W=nil then
|
||
begin
|
||
Desktop^.UnLock;
|
||
Found:=IDEApp.OpenSearch(P^.GetModuleName+'*');
|
||
if found then
|
||
W:=TryToOpenFile(nil,P^.GetModuleName,Col,Row,true);
|
||
Desktop^.Lock;
|
||
end;
|
||
if W<>nil then
|
||
begin
|
||
W^.Select;
|
||
W^.Editor^.TrackCursor(do_centre);
|
||
W^.Editor^.SetLineFlagExclusive(lfHighlightRow,Row);
|
||
end;
|
||
if Assigned(Owner) then
|
||
Owner^.Select;
|
||
Desktop^.UnLock;
|
||
end;
|
||
|
||
procedure TMessageListBox.GotoSource;
|
||
var W: PSourceWindow;
|
||
P: PMessageItem;
|
||
R:TRect;
|
||
Row,Col: sw_integer;
|
||
Found : boolean;
|
||
Event : TEvent;
|
||
begin
|
||
Message(Application,evBroadcast,cmClearLineHighlights,@Self);
|
||
if Range=0 then Exit;
|
||
P:=List^.At(Focused);
|
||
if P^.Row=0 then Exit;
|
||
Desktop^.Lock;
|
||
if P^.Row>0 then Row:=P^.Row-1 else Row:=0;
|
||
if P^.Col>0 then Col:=P^.Col-1 else Col:=0;
|
||
W:=EditorWindowFile(P^.GetModuleName);
|
||
if assigned(W) then
|
||
begin
|
||
W^.GetExtent(R);
|
||
if Owner^.Origin.Y>R.A.Y+4 then
|
||
R.B.Y:=Owner^.Origin.Y;
|
||
W^.ChangeBounds(R);
|
||
W^.Editor^.SetCurPtr(Col,Row);
|
||
end
|
||
else
|
||
W:=TryToOpenFile(nil,P^.GetModuleName,Col,Row,true);
|
||
{ Try to find it by browsing }
|
||
if W=nil then
|
||
begin
|
||
Desktop^.UnLock;
|
||
Found:=IDEApp.OpenSearch(P^.GetModuleName+'*');
|
||
if found then
|
||
W:=TryToOpenFile(nil,P^.GetModuleName,Col,Row,true);
|
||
Desktop^.Lock;
|
||
end;
|
||
if assigned(W) then
|
||
begin
|
||
{ Message(Owner,evCommand,cmClose,nil);
|
||
This calls close on StackWindow
|
||
rendering P invalid
|
||
so postpone it PM }
|
||
W^.GetExtent(R);
|
||
if (P^.TClass<>0) then
|
||
W^.Editor^.SetErrorMessage(P^.GetText(R.B.X-R.A.X));
|
||
W^.Select;
|
||
Owner^.Hide;
|
||
end;
|
||
Desktop^.UnLock;
|
||
if assigned(W) then
|
||
begin
|
||
Event.What:=evCommand;
|
||
Event.command:=cmClose;
|
||
Event.InfoPtr:=nil;
|
||
fpide.PutEvent(Owner,Event);
|
||
end;
|
||
end;
|
||
|
||
procedure TMessageListBox.Draw;
|
||
var
|
||
I, J, Item: Sw_Integer;
|
||
NormalColor, SelectedColor, FocusedColor, Color: Word;
|
||
ColWidth, CurCol, Indent: Integer;
|
||
B: TDrawBuffer;
|
||
Text: String;
|
||
SCOff: Byte;
|
||
TC: byte;
|
||
procedure MT(var C: word); begin if TC<>0 then C:=(C and $ff0f) or (TC and $f0); end;
|
||
begin
|
||
if (Owner<>nil) then TC:=ord(Owner^.GetColor(6)) else TC:=0;
|
||
if State and (sfSelected + sfActive) = (sfSelected + sfActive) then
|
||
begin
|
||
NormalColor := GetColor(1);
|
||
FocusedColor := GetColor(3);
|
||
SelectedColor := GetColor(4);
|
||
end else
|
||
begin
|
||
NormalColor := GetColor(2);
|
||
SelectedColor := GetColor(4);
|
||
end;
|
||
if Transparent then
|
||
begin MT(NormalColor); MT(SelectedColor); end;
|
||
if NoSelection then
|
||
SelectedColor:=NormalColor;
|
||
if HScrollBar <> nil then Indent := HScrollBar^.Value
|
||
else Indent := 0;
|
||
ColWidth := Size.X div NumCols + 1;
|
||
for I := 0 to Size.Y - 1 do
|
||
begin
|
||
for J := 0 to NumCols-1 do
|
||
begin
|
||
Item := J*Size.Y + I + TopItem;
|
||
CurCol := J*ColWidth;
|
||
if (State and (sfSelected + sfActive) = (sfSelected + sfActive)) and
|
||
(Focused = Item) and (Range > 0) then
|
||
begin
|
||
Color := FocusedColor;
|
||
SetCursor(CurCol+1,I);
|
||
SCOff := 0;
|
||
end
|
||
else if (Item < Range) and IsSelected(Item) then
|
||
begin
|
||
Color := SelectedColor;
|
||
SCOff := 2;
|
||
end
|
||
else
|
||
begin
|
||
Color := NormalColor;
|
||
SCOff := 4;
|
||
end;
|
||
MoveChar(B[CurCol], ' ', Color, ColWidth);
|
||
if Item < Range then
|
||
begin
|
||
Text := GetText(Item, ColWidth + Indent);
|
||
Text := Copy(Text,Indent,ColWidth);
|
||
MoveStr(B[CurCol+1], Text, Color);
|
||
if ShowMarkers then
|
||
begin
|
||
WordRec(B[CurCol]).Lo := Byte(SpecialChars[SCOff]);
|
||
WordRec(B[CurCol+ColWidth-2]).Lo := Byte(SpecialChars[SCOff+1]);
|
||
end;
|
||
end;
|
||
MoveChar(B[CurCol+ColWidth-1], #179, GetColor(5), 1);
|
||
end;
|
||
WriteLine(0, I, Size.X, 1, B);
|
||
end;
|
||
end;
|
||
|
||
constructor TMessageListBox.Load(var S: TStream);
|
||
begin
|
||
inherited Load(S);
|
||
New(ModuleNames, Init(50,100));
|
||
NoSelection:=true;
|
||
end;
|
||
|
||
procedure TMessageListBox.Store(var S: TStream);
|
||
var OL: PCollection;
|
||
ORV: sw_integer;
|
||
begin
|
||
OL:=List; ORV:=Range;
|
||
|
||
New(List, Init(1,1)); Range:=0;
|
||
|
||
inherited Store(S);
|
||
|
||
Dispose(List, Done);
|
||
List:=OL; Range:=ORV;
|
||
{ ^^^ nasty trick - has anyone a better idea how to avoid storing the
|
||
collection? Pasting here a modified version of TListBox.Store+
|
||
TAdvancedListBox.Store isn't a better solution, since by eventually
|
||
changing the obj-hierarchy you'll always have to modify this, too - BG }
|
||
end;
|
||
|
||
destructor TMessageListBox.Done;
|
||
begin
|
||
inherited Done;
|
||
if List<>nil then Dispose(List, Done);
|
||
if ModuleNames<>nil then Dispose(ModuleNames, Done);
|
||
end;
|
||
|
||
constructor TMessageItem.Init(AClass: longint; const AText: string; AModule: PString; ARow, ACol: sw_integer);
|
||
begin
|
||
inherited Init;
|
||
TClass:=AClass;
|
||
Text:=NewStr(AText);
|
||
Module:=AModule;
|
||
Row:=ARow; Col:=ACol;
|
||
end;
|
||
|
||
function TMessageItem.GetText(MaxLen: Sw_integer): string;
|
||
var S: string;
|
||
begin
|
||
if Text=nil then S:='' else S:=Text^;
|
||
if (Module<>nil) then
|
||
S:=NameAndExtOf(Module^)+'('+IntToStr(Row)+') '+S;
|
||
if length(S)>MaxLen then S:=copy(S,1,MaxLen-2)+'..';
|
||
GetText:=S;
|
||
end;
|
||
|
||
procedure TMessageItem.Selected;
|
||
begin
|
||
end;
|
||
|
||
function TMessageItem.GetModuleName: string;
|
||
begin
|
||
GetModuleName:=GetStr(Module);
|
||
end;
|
||
|
||
destructor TMessageItem.Done;
|
||
begin
|
||
inherited Done;
|
||
if Text<>nil then DisposeStr(Text);
|
||
{ if Module<>nil then DisposeStr(Module);}
|
||
end;
|
||
|
||
|
||
procedure TFPDlgWindow.HandleEvent(var Event: TEvent);
|
||
begin
|
||
case Event.What of
|
||
evBroadcast :
|
||
case Event.Command of
|
||
cmSearchWindow+1..cmSearchWindow+99 :
|
||
if (Event.Command-cmSearchWindow=Number) then
|
||
ClearEvent(Event);
|
||
end;
|
||
end;
|
||
inherited HandleEvent(Event);
|
||
end;
|
||
|
||
|
||
(*
|
||
constructor TTab.Init(var Bounds: TRect; ATabDef: PTabDef);
|
||
begin
|
||
inherited Init(Bounds);
|
||
Options:=Options or ofSelectable or ofFirstClick or ofPreProcess or ofPostProcess;
|
||
GrowMode:=gfGrowHiX+gfGrowHiY+gfGrowRel;
|
||
TabDefs:=ATabDef;
|
||
ActiveDef:=-1;
|
||
SelectTab(0);
|
||
ReDraw;
|
||
end;
|
||
|
||
function TTab.TabCount: integer;
|
||
var i: integer;
|
||
P: PTabDef;
|
||
begin
|
||
I:=0; P:=TabDefs;
|
||
while (P<>nil) do
|
||
begin
|
||
Inc(I);
|
||
P:=P^.Next;
|
||
end;
|
||
TabCount:=I;
|
||
end;
|
||
|
||
function TTab.AtTab(Index: integer): PTabDef;
|
||
var i: integer;
|
||
P: PTabDef;
|
||
begin
|
||
i:=0; P:=TabDefs;
|
||
while (I<Index) do
|
||
begin
|
||
if P=nil then RunError($AA);
|
||
P:=P^.Next;
|
||
Inc(i);
|
||
end;
|
||
AtTab:=P;
|
||
end;
|
||
|
||
procedure TTab.SelectTab(Index: integer);
|
||
var P: PTabItem;
|
||
V: PView;
|
||
begin
|
||
if ActiveDef<>Index then
|
||
begin
|
||
if Owner<>nil then Owner^.Lock;
|
||
Lock;
|
||
{ --- Update --- }
|
||
if TabDefs<>nil then
|
||
begin
|
||
DefCount:=1;
|
||
while AtTab(DefCount-1)^.Next<>nil do Inc(DefCount);
|
||
end
|
||
else DefCount:=0;
|
||
if ActiveDef<>-1 then
|
||
begin
|
||
P:=AtTab(ActiveDef)^.Items;
|
||
while P<>nil do
|
||
begin
|
||
if P^.View<>nil then Delete(P^.View);
|
||
P:=P^.Next;
|
||
end;
|
||
end;
|
||
ActiveDef:=Index;
|
||
P:=AtTab(ActiveDef)^.Items;
|
||
while P<>nil do
|
||
begin
|
||
if P^.View<>nil then Insert(P^.View);
|
||
P:=P^.Next;
|
||
end;
|
||
V:=AtTab(ActiveDef)^.DefItem;
|
||
if V<>nil then V^.Select;
|
||
ReDraw;
|
||
{ --- Update --- }
|
||
UnLock;
|
||
if Owner<>nil then Owner^.UnLock;
|
||
DrawView;
|
||
end;
|
||
end;
|
||
|
||
procedure TTab.ChangeBounds(var Bounds: TRect);
|
||
var D: TPoint;
|
||
procedure DoCalcChange(P: PView);
|
||
var
|
||
R: TRect;
|
||
begin
|
||
if P^.Owner=nil then Exit; { it think this is a bug in TV }
|
||
P^.CalcBounds(R, D);
|
||
P^.ChangeBounds(R);
|
||
end;
|
||
var
|
||
P: PTabItem;
|
||
I: integer;
|
||
begin
|
||
D.X := Bounds.B.X - Bounds.A.X - Size.X;
|
||
D.Y := Bounds.B.Y - Bounds.A.Y - Size.Y;
|
||
inherited ChangeBounds(Bounds);
|
||
for I:=0 to TabCount-1 do
|
||
if I<>ActiveDef then
|
||
begin
|
||
P:=AtTab(I)^.Items;
|
||
while P<>nil do
|
||
begin
|
||
if P^.View<>nil then DoCalcChange(P^.View);
|
||
P:=P^.Next;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure TTab.SelectNextTab(Forwards: boolean);
|
||
var Index: integer;
|
||
begin
|
||
Index:=ActiveDef;
|
||
if Index=-1 then Exit;
|
||
if Forwards then Inc(Index) else Dec(Index);
|
||
if Index<0 then Index:=DefCount-1 else
|
||
if Index>DefCount-1 then Index:=0;
|
||
SelectTab(Index);
|
||
end;
|
||
|
||
procedure TTab.HandleEvent(var Event: TEvent);
|
||
var Index : integer;
|
||
I : integer;
|
||
X : integer;
|
||
Len : byte;
|
||
P : TPoint;
|
||
V : PView;
|
||
CallOrig: boolean;
|
||
LastV : PView;
|
||
FirstV: PView;
|
||
function FirstSelectable: PView;
|
||
var
|
||
FV : PView;
|
||
begin
|
||
FV := First;
|
||
while (FV<>nil) and ((FV^.Options and ofSelectable)=0) and (FV<>Last) do
|
||
FV:=FV^.Next;
|
||
if FV<>nil then
|
||
if (FV^.Options and ofSelectable)=0 then FV:=nil;
|
||
FirstSelectable:=FV;
|
||
end;
|
||
function LastSelectable: PView;
|
||
var
|
||
LV : PView;
|
||
begin
|
||
LV := Last;
|
||
while (LV<>nil) and ((LV^.Options and ofSelectable)=0) and (LV<>First) do
|
||
LV:=LV^.Prev;
|
||
if LV<>nil then
|
||
if (LV^.Options and ofSelectable)=0 then LV:=nil;
|
||
LastSelectable:=LV;
|
||
end;
|
||
begin
|
||
if (Event.What and evMouseDown)<>0 then
|
||
begin
|
||
MakeLocal(Event.Where,P);
|
||
if P.Y<3 then
|
||
begin
|
||
Index:=-1; X:=1;
|
||
for i:=0 to DefCount-1 do
|
||
begin
|
||
Len:=CStrLen(AtTab(i)^.Name^);
|
||
if (P.X>=X) and (P.X<=X+Len+1) then Index:=i;
|
||
X:=X+Len+3;
|
||
end;
|
||
if Index<>-1 then
|
||
SelectTab(Index);
|
||
end;
|
||
end;
|
||
if Event.What=evKeyDown then
|
||
begin
|
||
Index:=-1;
|
||
case Event.KeyCode of
|
||
kbCtrlTab :
|
||
begin
|
||
SelectNextTab((Event.KeyShift and kbShift)=0);
|
||
ClearEvent(Event);
|
||
end;
|
||
kbTab,kbShiftTab :
|
||
if GetState(sfSelected) then
|
||
begin
|
||
if Current<>nil then
|
||
begin
|
||
LastV:=LastSelectable; FirstV:=FirstSelectable;
|
||
if ((Current=LastV) or (Current=PLabel(LastV)^.Link)) and (Event.KeyCode=kbShiftTab) then
|
||
begin
|
||
if Owner<>nil then Owner^.SelectNext(true);
|
||
end else
|
||
if ((Current=FirstV) or (Current=PLabel(FirstV)^.Link)) and (Event.KeyCode=kbTab) then
|
||
begin
|
||
Lock;
|
||
if Owner<>nil then Owner^.SelectNext(false);
|
||
UnLock;
|
||
end else
|
||
SelectNext(Event.KeyCode=kbShiftTab);
|
||
ClearEvent(Event);
|
||
end;
|
||
end;
|
||
else
|
||
for I:=0 to DefCount-1 do
|
||
begin
|
||
if Upcase(GetAltChar(Event.KeyCode))=AtTab(I)^.ShortCut
|
||
then begin
|
||
Index:=I;
|
||
ClearEvent(Event);
|
||
Break;
|
||
end;
|
||
end;
|
||
end;
|
||
if Index<>-1 then
|
||
begin
|
||
Select;
|
||
SelectTab(Index);
|
||
V:=AtTab(ActiveDef)^.DefItem;
|
||
if V<>nil then V^.Focus;
|
||
end;
|
||
end;
|
||
CallOrig:=true;
|
||
if Event.What=evKeyDown then
|
||
begin
|
||
if ((Owner<>nil) and (Owner^.Phase=phPostProcess) and (GetAltChar(Event.KeyCode)<>#0)) or GetState(sfFocused)
|
||
then
|
||
else CallOrig:=false;
|
||
end;
|
||
if CallOrig then inherited HandleEvent(Event);
|
||
end;
|
||
|
||
function TTab.GetPalette: PPalette;
|
||
begin
|
||
GetPalette:=nil;
|
||
end;
|
||
|
||
procedure TTab.Draw;
|
||
var B : TDrawBuffer;
|
||
i : integer;
|
||
C1,C2,C3,C : word;
|
||
HeaderLen : integer;
|
||
X,X2 : integer;
|
||
Name : PString;
|
||
ActiveKPos : integer;
|
||
ActiveVPos : integer;
|
||
FC : char;
|
||
ClipR : TRect;
|
||
procedure SWriteBuf(X,Y,W,H: integer; var Buf);
|
||
var i: integer;
|
||
begin
|
||
if Y+H>Size.Y then H:=Size.Y-Y;
|
||
if X+W>Size.X then W:=Size.X-X;
|
||
if Buffer=nil then WriteBuf(X,Y,W,H,Buf)
|
||
else for i:=1 to H do
|
||
Move(Buf,Buffer^[X+(Y+i-1)*Size.X],W*2);
|
||
end;
|
||
procedure ClearBuf;
|
||
begin
|
||
MoveChar(B,' ',C1,Size.X);
|
||
end;
|
||
begin
|
||
if InDraw then Exit;
|
||
InDraw:=true;
|
||
{ - Start of TGroup.Draw - }
|
||
{ if Buffer = nil then
|
||
begin
|
||
GetBuffer;
|
||
end; }
|
||
{ - Start of TGroup.Draw - }
|
||
|
||
C1:=GetColor(1); C2:=(GetColor(7) and $f0 or $08)+GetColor(9)*256; C3:=GetColor(8)+GetColor({9}8)*256;
|
||
HeaderLen:=0; for i:=0 to DefCount-1 do HeaderLen:=HeaderLen+CStrLen(AtTab(i)^.Name^)+3; Dec(HeaderLen);
|
||
if HeaderLen>Size.X-2 then HeaderLen:=Size.X-2;
|
||
|
||
{ --- 1. sor --- }
|
||
ClearBuf; MoveChar(B[0],'<27>',C1,1); MoveChar(B[HeaderLen+1],'<27>',C1,1);
|
||
X:=1;
|
||
for i:=0 to DefCount-1 do
|
||
begin
|
||
Name:=AtTab(i)^.Name; X2:=CStrLen(Name^);
|
||
if i=ActiveDef
|
||
then begin
|
||
ActiveKPos:=X-1;
|
||
ActiveVPos:=X+X2+2;
|
||
if GetState(sfFocused) then C:=C3 else C:=C2;
|
||
end
|
||
else C:=C2;
|
||
MoveCStr(B[X],' '+Name^+' ',C); X:=X+X2+3;
|
||
MoveChar(B[X-1],'<27>',C1,1);
|
||
end;
|
||
SWriteBuf(0,1,Size.X,1,B);
|
||
|
||
{ --- 0. sor --- }
|
||
ClearBuf; MoveChar(B[0],'<27>',C1,1);
|
||
X:=1;
|
||
for i:=0 to DefCount-1 do
|
||
begin
|
||
if I<ActiveDef then FC:='<27>'
|
||
else FC:='<27>';
|
||
X2:=CStrLen(AtTab(i)^.Name^)+2;
|
||
MoveChar(B[X+X2],{'<27>'}FC,C1,1);
|
||
if i=DefCount-1 then X2:=X2+1;
|
||
if X2>0 then
|
||
MoveChar(B[X],'<27>',C1,X2);
|
||
X:=X+X2+1;
|
||
end;
|
||
MoveChar(B[HeaderLen+1],'<27>',C1,1);
|
||
MoveChar(B[ActiveKPos],'<27>',C1,1); MoveChar(B[ActiveVPos],'<27>',C1,1);
|
||
SWriteBuf(0,0,Size.X,1,B);
|
||
|
||
{ --- 2. sor --- }
|
||
MoveChar(B[1],'<27>',C1,Max(HeaderLen,0)); MoveChar(B[HeaderLen+2],'<27>',C1,Max(Size.X-HeaderLen-3,0));
|
||
MoveChar(B[Size.X-1],'<27>',C1,1);
|
||
MoveChar(B[ActiveKPos],'<27>',C1,1);
|
||
if ActiveDef=0 then MoveChar(B[0],'<27>',C1,1)
|
||
else MoveChar(B[0],{'<27>'}'<27>',C1,1);
|
||
MoveChar(B[HeaderLen+1],'<27>'{'<27>'},C1,1); MoveChar(B[ActiveVPos],'<27>',C1,1);
|
||
MoveChar(B[ActiveKPos+1],' ',C1,Max(ActiveVPos-ActiveKPos-1,0));
|
||
SWriteBuf(0,2,Size.X,1,B);
|
||
|
||
{ --- marad<61>k sor --- }
|
||
ClearBuf; MoveChar(B[0],'<27>',C1,1); MoveChar(B[Size.X-1],'<27>',C1,1);
|
||
for i:=3 to Size.Y-1 do
|
||
SWriteBuf(0,i,Size.X,1,B);
|
||
{ SWriteBuf(0,3,Size.X,Size.Y-4,B); this was wrong
|
||
because WriteBuf then expect a buffer of size size.x*(size.y-4)*2 PM }
|
||
|
||
{ --- Size.X . sor --- }
|
||
MoveChar(B[0],'<27>',C1,1); MoveChar(B[1],'<27>',C1,Max(Size.X-2,0)); MoveChar(B[Size.X-1],'<27>',C1,1);
|
||
SWriteBuf(0,Size.Y-1,Size.X,1,B);
|
||
|
||
{ - End of TGroup.Draw - }
|
||
if Buffer <> nil then
|
||
begin
|
||
Lock;
|
||
Redraw;
|
||
UnLock;
|
||
end;
|
||
if Buffer <> nil then WriteBuf(0, 0, Size.X, Size.Y, Buffer^) else
|
||
begin
|
||
GetClipRect(ClipR);
|
||
Redraw;
|
||
GetExtent(ClipR);
|
||
end;
|
||
{ - End of TGroup.Draw - }
|
||
InDraw:=false;
|
||
end;
|
||
|
||
function TTab.Valid(Command: Word): Boolean;
|
||
var PT : PTabDef;
|
||
PI : PTabItem;
|
||
OK : boolean;
|
||
begin
|
||
OK:=true;
|
||
PT:=TabDefs;
|
||
while (PT<>nil) and (OK=true) do
|
||
begin
|
||
PI:=PT^.Items;
|
||
while (PI<>nil) and (OK=true) do
|
||
begin
|
||
if PI^.View<>nil then OK:=OK and PI^.View^.Valid(Command);
|
||
PI:=PI^.Next;
|
||
end;
|
||
PT:=PT^.Next;
|
||
end;
|
||
Valid:=OK;
|
||
end;
|
||
|
||
procedure TTab.SetState(AState: Word; Enable: Boolean);
|
||
begin
|
||
inherited SetState(AState,Enable);
|
||
if (AState and sfFocused)<>0 then DrawView;
|
||
end;
|
||
|
||
destructor TTab.Done;
|
||
var P,X: PTabDef;
|
||
procedure DeleteViews(P: PView);
|
||
begin
|
||
if P<>nil then Delete(P);
|
||
end;
|
||
begin
|
||
ForEach(@DeleteViews);
|
||
inherited Done;
|
||
P:=TabDefs;
|
||
while P<>nil do
|
||
begin
|
||
X:=P^.Next;
|
||
DisposeTabDef(P);
|
||
P:=X;
|
||
end;
|
||
end;
|
||
*)
|
||
|
||
|
||
constructor TScreenView.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar;
|
||
AScreen: PScreen);
|
||
begin
|
||
inherited Init(Bounds,AHScrollBar,AVScrollBar);
|
||
Screen:=AScreen;
|
||
if Screen=nil then
|
||
Fail;
|
||
SetState(sfCursorVis,true);
|
||
Update;
|
||
end;
|
||
|
||
procedure TScreenView.Update;
|
||
begin
|
||
SetLimit(UserScreen^.GetWidth,UserScreen^.GetHeight);
|
||
DrawView;
|
||
end;
|
||
|
||
procedure TScreenView.HandleEvent(var Event: TEvent);
|
||
begin
|
||
case Event.What of
|
||
evBroadcast :
|
||
case Event.Command of
|
||
cmUpdate : Update;
|
||
end;
|
||
end;
|
||
inherited HandleEvent(Event);
|
||
end;
|
||
|
||
procedure TScreenView.Draw;
|
||
var B: TDrawBuffer;
|
||
X,Y: integer;
|
||
Text,Attr: string;
|
||
P: TPoint;
|
||
begin
|
||
Screen^.GetCursorPos(P);
|
||
for Y:=Delta.Y to Delta.Y+Size.Y-1 do
|
||
begin
|
||
if Y<Screen^.GetHeight then
|
||
Screen^.GetLine(Y,Text,Attr)
|
||
else
|
||
begin Text:=''; Attr:=''; end;
|
||
Text:=copy(Text,Delta.X+1,255); Attr:=copy(Attr,Delta.X+1,255);
|
||
MoveChar(B,' ',GetColor(1),Size.X);
|
||
for X:=1 to length(Text) do
|
||
MoveChar(B[X-1],Text[X],ord(Attr[X]),1);
|
||
WriteLine(0,Y-Delta.Y,Size.X,1,B);
|
||
end;
|
||
SetCursor(P.X-Delta.X,P.Y-Delta.Y);
|
||
end;
|
||
|
||
constructor TScreenWindow.Init(AScreen: PScreen; ANumber: integer);
|
||
var R: TRect;
|
||
VSB,HSB: PScrollBar;
|
||
begin
|
||
Desktop^.GetExtent(R);
|
||
inherited Init(R, dialog_userscreen, ANumber);
|
||
Options:=Options or ofTileAble;
|
||
GetExtent(R); R.Grow(-1,-1); R.Move(1,0); R.A.X:=R.B.X-1;
|
||
New(VSB, Init(R)); VSB^.Options:=VSB^.Options or ofPostProcess;
|
||
VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY; Insert(VSB);
|
||
GetExtent(R); R.Grow(-1,-1); R.Move(0,1); R.A.Y:=R.B.Y-1;
|
||
New(HSB, Init(R)); HSB^.Options:=HSB^.Options or ofPostProcess;
|
||
HSB^.GrowMode:=gfGrowLoY+gfGrowHiX+gfGrowHiY; Insert(HSB);
|
||
GetExtent(R); R.Grow(-1,-1);
|
||
New(ScreenView, Init(R, HSB, VSB, AScreen));
|
||
ScreenView^.GrowMode:=gfGrowHiX+gfGrowHiY;
|
||
Insert(ScreenView);
|
||
UserScreenWindow:=@Self;
|
||
end;
|
||
|
||
destructor TScreenWindow.Done;
|
||
begin
|
||
inherited Done;
|
||
UserScreenWindow:=nil;
|
||
end;
|
||
|
||
const InTranslate : boolean = false;
|
||
|
||
procedure TranslateMouseClick(View: PView; var Event: TEvent);
|
||
procedure TranslateAction(Action: integer);
|
||
var E: TEvent;
|
||
begin
|
||
if Action<>acNone then
|
||
begin
|
||
E:=Event;
|
||
E.What:=evMouseDown; E.Buttons:=mbLeftButton;
|
||
View^.HandleEvent(E);
|
||
Event.What:=evCommand;
|
||
Event.Command:=ActionCommands[Action];
|
||
end;
|
||
end;
|
||
begin
|
||
if InTranslate then Exit;
|
||
InTranslate:=true;
|
||
case Event.What of
|
||
evMouseDown :
|
||
if (GetShiftState and kbAlt)<>0 then
|
||
TranslateAction(AltMouseAction) else
|
||
if (GetShiftState and kbCtrl)<>0 then
|
||
TranslateAction(CtrlMouseAction);
|
||
end;
|
||
InTranslate:=false;
|
||
end;
|
||
|
||
function GetNextEditorBounds(var Bounds: TRect): boolean;
|
||
var P: PView;
|
||
begin
|
||
P:=Desktop^.Current;
|
||
while P<>nil do
|
||
begin
|
||
if P^.HelpCtx=hcSourceWindow then Break;
|
||
P:=P^.NextView;
|
||
if P=Desktop^.Current then
|
||
begin
|
||
P:=nil;
|
||
break;
|
||
end;
|
||
end;
|
||
if P=nil then Desktop^.GetExtent(Bounds) else
|
||
begin
|
||
P^.GetBounds(Bounds);
|
||
Inc(Bounds.A.X); Inc(Bounds.A.Y);
|
||
end;
|
||
GetNextEditorBounds:=P<>nil;
|
||
end;
|
||
|
||
function IOpenEditorWindow(Bounds: PRect; FileName: string; CurX,CurY: sw_integer; ShowIt: boolean): PSourceWindow;
|
||
var R: TRect;
|
||
W: PSourceWindow;
|
||
begin
|
||
if Assigned(Bounds) then R.Copy(Bounds^) else
|
||
GetNextEditorBounds(R);
|
||
PushStatus(FormatStrStr(msg_openingsourcefile,SmartPath(FileName)));
|
||
New(W, Init(R, FileName));
|
||
if ShowIt=false then
|
||
W^.Hide;
|
||
if W<>nil then
|
||
begin
|
||
if (CurX<>0) or (CurY<>0) then
|
||
with W^.Editor^ do
|
||
begin
|
||
SetCurPtr(CurX,CurY);
|
||
TrackCursor(do_centre);
|
||
end;
|
||
W^.HelpCtx:=hcSourceWindow;
|
||
Desktop^.Insert(W);
|
||
{ this makes loading a lot slower and is not needed as far as I can see (FK)
|
||
Message(Application,evBroadcast,cmUpdate,nil);
|
||
}
|
||
end;
|
||
PopStatus;
|
||
IOpenEditorWindow:=W;
|
||
end;
|
||
|
||
function OpenEditorWindow(Bounds: PRect; FileName: string; CurX,CurY: sw_integer): PSourceWindow;
|
||
begin
|
||
OpenEditorWindow:=IOpenEditorWindow(Bounds,FileName,CurX,CurY,true);
|
||
end;
|
||
|
||
|
||
function LastSourceEditor : PSourceWindow;
|
||
|
||
function IsSearchedSource(P: PView) : boolean;
|
||
begin
|
||
if assigned(P) and
|
||
(TypeOf(P^)=TypeOf(TSourceWindow)) then
|
||
IsSearchedSource:=true
|
||
else
|
||
IsSearchedSource:=false;
|
||
end;
|
||
|
||
begin
|
||
LastSourceEditor:=PSourceWindow(Desktop^.FirstThat(@IsSearchedSource));
|
||
end;
|
||
|
||
|
||
function SearchOnDesktop(FileName : string;tryexts:boolean) : PSourceWindow;
|
||
var
|
||
D,DS : DirStr;
|
||
N,NS : NameStr;
|
||
E,ES : ExtStr;
|
||
SName : string;
|
||
|
||
function IsSearchedFile(W : PSourceWindow) : boolean;
|
||
var Found: boolean;
|
||
begin
|
||
Found:=false;
|
||
if (W<>nil) and (W^.HelpCtx=hcSourceWindow) then
|
||
begin
|
||
if (D='') then
|
||
SName:=NameAndExtOf(PSourceWindow(W)^.Editor^.FileName)
|
||
else
|
||
SName:=PSourceWindow(W)^.Editor^.FileName;
|
||
FSplit(SName,DS,NS,ES);
|
||
SName:=UpcaseStr(NS+ES);
|
||
|
||
if (E<>'') or (not tryexts) then
|
||
begin
|
||
if D<>'' then
|
||
Found:=UpCaseStr(DS)+SName=UpcaseStr(D+N+E)
|
||
else
|
||
Found:=SName=UpcaseStr(N+E);
|
||
end
|
||
else
|
||
begin
|
||
Found:=SName=UpcaseStr(N+'.pp');
|
||
if Found=false then
|
||
Found:=SName=UpcaseStr(N+'.pas');
|
||
end;
|
||
end;
|
||
IsSearchedFile:=found;
|
||
end;
|
||
function IsSearchedSource(P: PView) : boolean;
|
||
begin
|
||
if assigned(P) and
|
||
(TypeOf(P^)=TypeOf(TSourceWindow)) then
|
||
IsSearchedSource:=IsSearchedFile(PSourceWindow(P))
|
||
else
|
||
IsSearchedSource:=false;
|
||
end;
|
||
|
||
begin
|
||
FSplit(FileName,D,N,E);
|
||
SearchOnDesktop:=PSourceWindow(Desktop^.FirstThat(@IsSearchedSource));
|
||
end;
|
||
|
||
function TryToOpenFile(Bounds: PRect; FileName: string; CurX,CurY: sw_integer;tryexts:boolean): PSourceWindow;
|
||
begin
|
||
TryToOpenFile:=ITryToOpenFile(Bounds,FileName,CurX,CurY,tryexts,true,false);
|
||
end;
|
||
|
||
function TryToOpenFileMulti(Bounds: PRect; FileName: string; CurX,CurY: sw_integer;tryexts:boolean): PSourceWindow;
|
||
var srec:SearchRec;
|
||
dir,name,ext : string;
|
||
begin
|
||
fsplit(filename,dir,name,ext);
|
||
dir:=completedir(dir);
|
||
FindFirst(filename,anyfile,Srec);
|
||
while (DosError=0) do
|
||
begin
|
||
ITryToOpenFile(Bounds,dir+srec.name,CurX,CurY,tryexts,true,false);
|
||
FindNext(srec);
|
||
end;
|
||
FindClose(srec);
|
||
end;
|
||
|
||
|
||
function LocateSingleSourceFile(const FileName: string; tryexts: boolean): string;
|
||
var D : DirStr;
|
||
N : NameStr;
|
||
E : ExtStr;
|
||
|
||
function CheckDir(NewDir: DirStr; NewName: NameStr; NewExt: ExtStr): boolean;
|
||
var OK: boolean;
|
||
begin
|
||
NewDir:=CompleteDir(NewDir);
|
||
OK:=ExistsFile(NewDir+NewName+NewExt);
|
||
if OK then begin D:=NewDir; N:=NewName; E:=NewExt; end;
|
||
CheckDir:=OK;
|
||
end;
|
||
|
||
function CheckExt(NewExt: ExtStr): boolean;
|
||
var OK: boolean;
|
||
begin
|
||
OK:=false;
|
||
if D<>'' then OK:=CheckDir(D,N,NewExt) else
|
||
if CheckDir('.'+DirSep,N,NewExt) then OK:=true;
|
||
CheckExt:=OK;
|
||
end;
|
||
|
||
function TryToLocateIn(const DD : dirstr): boolean;
|
||
var Found: boolean;
|
||
begin
|
||
D:=CompleteDir(DD);
|
||
Found:=true;
|
||
if (E<>'') or (not tryexts) then
|
||
Found:=CheckExt(E)
|
||
else
|
||
if CheckExt('.pp') then
|
||
Found:=true
|
||
else
|
||
if CheckExt('.pas') then
|
||
Found:=true
|
||
else
|
||
if CheckExt('.inc') then
|
||
Found:=true
|
||
{ try also without extension if no other exist }
|
||
else
|
||
if CheckExt('') then
|
||
Found:=true
|
||
else
|
||
Found:=false;
|
||
TryToLocateIn:=Found;
|
||
end;
|
||
var Path,DrStr: string;
|
||
Found: boolean;
|
||
begin
|
||
FSplit(FileName,D,N,E);
|
||
Found:=CheckDir(D,N,E);
|
||
if not found then
|
||
Found:=TryToLocateIn('.');
|
||
DrStr:=GetSourceDirectories;
|
||
if not Found then
|
||
While pos(ListSeparator,DrStr)>0 do
|
||
Begin
|
||
Found:=TryToLocateIn(Copy(DrStr,1,pos(ListSeparator,DrStr)-1));
|
||
if Found then
|
||
break;
|
||
DrStr:=Copy(DrStr,pos(ListSeparator,DrStr)+1,High(DrStr));
|
||
End;
|
||
if Found then Path:=FExpand(D+N+E) else Path:='';
|
||
LocateSingleSourceFile:=Path;
|
||
end;
|
||
|
||
function LocateSourceFile(const FileName: string; tryexts: boolean): string;
|
||
var P: integer;
|
||
FN,S: string;
|
||
FFN: string;
|
||
begin
|
||
FN:=FileName;
|
||
repeat
|
||
P:=Pos(ListSeparator,FN); if P=0 then P:=length(FN)+1;
|
||
S:=copy(FN,1,P-1); Delete(FN,1,P);
|
||
FFN:=LocateSingleSourceFile(S,tryexts);
|
||
until (FFN<>'') or (FN='');
|
||
LocateSourceFile:=FFN;
|
||
end;
|
||
|
||
function ITryToOpenFile(Bounds: PRect; FileName: string; CurX,CurY: sw_integer;tryexts:boolean;
|
||
ShowIt,ForceNewWindow: boolean): PSourceWindow;
|
||
var
|
||
W : PSourceWindow;
|
||
DrStr: string;
|
||
begin
|
||
W:=nil;
|
||
if ForceNewWindow then
|
||
W:=nil
|
||
else
|
||
W:=SearchOnDesktop(FileName,tryexts);
|
||
if W<>nil then
|
||
begin
|
||
NewEditorOpened:=false;
|
||
{ if assigned(Bounds) then
|
||
W^.ChangeBounds(Bounds^);}
|
||
W^.Editor^.SetCurPtr(CurX,CurY);
|
||
end
|
||
else
|
||
begin
|
||
DrStr:=LocateSourceFile(FileName,tryexts);
|
||
if DrStr<>'' then
|
||
W:=IOpenEditorWindow(Bounds,DrStr,CurX,CurY,ShowIt);
|
||
NewEditorOpened:=W<>nil;
|
||
if assigned(W) then
|
||
W^.Editor^.SetCurPtr(CurX,CurY);
|
||
end;
|
||
ITryToOpenFile:=W;
|
||
end;
|
||
|
||
function StartEditor(Editor: PCodeEditor; FileName: string): boolean;
|
||
var OK: boolean;
|
||
E: PFileEditor;
|
||
R: TRect;
|
||
begin
|
||
R.Assign(0,0,0,0);
|
||
New(E, Init(R,nil,nil,nil,nil,FileName));
|
||
OK:=E<>nil;
|
||
if OK then
|
||
begin
|
||
PushStatus(FormatStrStr(msg_readingfileineditor,FileName));
|
||
OK:=E^.LoadFile;
|
||
PopStatus;
|
||
end;
|
||
if OK then
|
||
begin
|
||
Editor^.Lock;
|
||
E^.SelectAll(true);
|
||
Editor^.InsertFrom(E);
|
||
Editor^.SetCurPtr(0,0);
|
||
Editor^.SelectAll(false);
|
||
Editor^.UnLock;
|
||
Dispose(E, Done);
|
||
end;
|
||
StartEditor:=OK;
|
||
end;
|
||
|
||
constructor TTextScroller.Init(var Bounds: TRect; ASpeed: integer; AText: PUnsortedStringCollection);
|
||
begin
|
||
inherited Init(Bounds,'');
|
||
EventMask:=EventMask or evIdle;
|
||
Speed:=ASpeed; Lines:=AText;
|
||
end;
|
||
|
||
function TTextScroller.GetLineCount: integer;
|
||
var Count: integer;
|
||
begin
|
||
if Lines=nil then Count:=0 else
|
||
Count:=Lines^.Count;
|
||
GetLineCount:=Count;
|
||
end;
|
||
|
||
function TTextScroller.GetLine(I: integer): string;
|
||
var S: string;
|
||
begin
|
||
if I<Lines^.Count then
|
||
S:=GetStr(Lines^.At(I))
|
||
else
|
||
S:='';
|
||
GetLine:=S;
|
||
end;
|
||
|
||
procedure TTextScroller.HandleEvent(var Event: TEvent);
|
||
begin
|
||
case Event.What of
|
||
evIdle :
|
||
Update;
|
||
end;
|
||
inherited HandleEvent(Event);
|
||
end;
|
||
|
||
procedure TTextScroller.Update;
|
||
begin
|
||
if abs(GetDosTicks-LastTT)<Speed then Exit;
|
||
Scroll;
|
||
LastTT:=GetDosTicks;
|
||
end;
|
||
|
||
procedure TTextScroller.Reset;
|
||
begin
|
||
TopLine:=0;
|
||
LastTT:=GetDosTicks;
|
||
DrawView;
|
||
end;
|
||
|
||
procedure TTextScroller.Scroll;
|
||
begin
|
||
Inc(TopLine);
|
||
if TopLine>=GetLineCount then
|
||
Reset;
|
||
DrawView;
|
||
end;
|
||
|
||
procedure TTextScroller.Draw;
|
||
var B: TDrawBuffer;
|
||
C: word;
|
||
Count,Y: integer;
|
||
S: string;
|
||
begin
|
||
C:=GetColor(1);
|
||
Count:=GetLineCount;
|
||
for Y:=0 to Size.Y-1 do
|
||
begin
|
||
if Count=0 then S:='' else
|
||
S:=GetLine((TopLine+Y) mod Count);
|
||
if copy(S,1,1)=^C then
|
||
S:=CharStr(' ',Max(0,(Size.X-(length(S)-1)) div 2))+copy(S,2,255);
|
||
MoveChar(B,' ',C,Size.X);
|
||
MoveStr(B,S,C);
|
||
WriteLine(0,Y,Size.X,1,B);
|
||
end;
|
||
end;
|
||
|
||
destructor TTextScroller.Done;
|
||
begin
|
||
inherited Done;
|
||
if Lines<>nil then Dispose(Lines, Done);
|
||
end;
|
||
|
||
constructor TFPAboutDialog.Init;
|
||
var R,R2: TRect;
|
||
C: PUnsortedStringCollection;
|
||
I: integer;
|
||
OSStr: string;
|
||
procedure AddLine(S: string);
|
||
begin
|
||
C^.Insert(NewStr(S));
|
||
end;
|
||
begin
|
||
R.Assign(0,0,58,14{$ifdef NODEBUG}-1{$endif});
|
||
inherited Init(R, dialog_about);
|
||
HelpCtx:=hcAbout;
|
||
GetExtent(R); R.Grow(-3,-2);
|
||
R2.Copy(R); R2.B.Y:=R2.A.Y+1;
|
||
Insert(New(PStaticText, Init(R2, ^C'FreePascal IDE for '+source_info.name)));
|
||
R2.Move(0,1);
|
||
Insert(New(PStaticText, Init(R2, ^C'Target CPU: '+target_cpu_string)));
|
||
R2.Move(0,1);
|
||
Insert(New(PStaticText, Init(R2, ^C'Version '+VersionStr+' '+{$i %date%})));
|
||
R2.Move(0,1);
|
||
{$ifdef USE_GRAPH_SWITCH}
|
||
Insert(New(PStaticText, Init(R2, ^C'With Graphic Support')));
|
||
R2.Move(0,1);
|
||
{$endif USE_GRAPH_SWITCH}
|
||
Insert(New(PStaticText, Init(R2, FormatStrStr2(^C'(%s %s)',label_about_compilerversion,Full_Version_String))));
|
||
{$ifndef NODEBUG}
|
||
if pos('Fake',GDBVersion)=0 then
|
||
begin
|
||
R2.Move(0,1);
|
||
Insert(New(PStaticText, Init(R2, FormatStrStr2(^C'(%s %s)',label_about_debugger,GDBVersion))));
|
||
R2.Move(0,1);
|
||
end
|
||
else
|
||
{$endif NODEBUG}
|
||
R2.Move(0,2);
|
||
Insert(New(PStaticText, Init(R2, ^C'Copyright (C) 1998-2011 by')));
|
||
R2.Move(0,2);
|
||
Insert(New(PStaticText, Init(R2, ^C'B<>rczi G<>bor')));
|
||
R2.Move(0,1);
|
||
Insert(New(PStaticText, Init(R2, ^C'Pierre Muller')));
|
||
R2.Move(0,1);
|
||
Insert(New(PStaticText, Init(R2, ^C'and')));
|
||
R2.Move(0,1);
|
||
Insert(New(PStaticText, Init(R2, ^C'Peter Vreman')));
|
||
New(C, Init(50,10));
|
||
for I:=1 to 7 do
|
||
AddLine('');
|
||
AddLine(^C'< Original concept >');
|
||
AddLine(^C'Borland International, Inc.');
|
||
AddLine('');
|
||
AddLine(^C'< Compiler development >');
|
||
AddLine(^C'Carl-Eric Codere');
|
||
AddLine(^C'Daniel Mantione');
|
||
AddLine(^C'Florian Kl<4B>mpfl');
|
||
AddLine(^C'Jonas Maebe');
|
||
AddLine(^C'Mich<63>el Van Canneyt');
|
||
AddLine(^C'Peter Vreman');
|
||
AddLine(^C'Pierre Muller');
|
||
AddLine('');
|
||
AddLine(^C'< IDE development >');
|
||
AddLine(^C'B<>rczi G<>bor');
|
||
AddLine(^C'Peter Vreman');
|
||
AddLine(^C'Pierre Muller');
|
||
AddLine('');
|
||
|
||
GetExtent(R);
|
||
R.Grow(-1,-1); Inc(R.A.Y,3);
|
||
New(Scroller, Init(R, 10, C));
|
||
Scroller^.Hide;
|
||
Insert(Scroller);
|
||
R.Move(0,-1); R.B.Y:=R.A.Y+1;
|
||
New(TitleST, Init(R, ^C'Team'));
|
||
TitleST^.Hide;
|
||
Insert(TitleST);
|
||
|
||
InsertOK(@Self);
|
||
end;
|
||
|
||
procedure TFPAboutDialog.ToggleInfo;
|
||
begin
|
||
if Scroller=nil then Exit;
|
||
if Scroller^.GetState(sfVisible) then
|
||
begin
|
||
Scroller^.Hide;
|
||
TitleST^.Hide;
|
||
end
|
||
else
|
||
begin
|
||
Scroller^.Reset;
|
||
Scroller^.Show;
|
||
TitleST^.Show;
|
||
end;
|
||
end;
|
||
|
||
procedure TFPAboutDialog.HandleEvent(var Event: TEvent);
|
||
begin
|
||
case Event.What of
|
||
evKeyDown :
|
||
case Event.KeyCode of
|
||
kbAltI : { just like in BP }
|
||
begin
|
||
ToggleInfo;
|
||
ClearEvent(Event);
|
||
end;
|
||
end;
|
||
end;
|
||
inherited HandleEvent(Event);
|
||
end;
|
||
|
||
constructor TFPASCIIChart.Init;
|
||
begin
|
||
inherited Init;
|
||
HelpCtx:=hcASCIITableWindow;
|
||
Number:=SearchFreeWindowNo;
|
||
ASCIIChart:=@Self;
|
||
end;
|
||
|
||
procedure TFPASCIIChart.Store(var S: TStream);
|
||
begin
|
||
inherited Store(S);
|
||
end;
|
||
|
||
constructor TFPASCIIChart.Load(var S: TStream);
|
||
begin
|
||
inherited Load(S);
|
||
end;
|
||
|
||
procedure TFPASCIIChart.HandleEvent(var Event: TEvent);
|
||
var W: PSourceWindow;
|
||
begin
|
||
case Event.What of
|
||
evKeyDown :
|
||
case Event.KeyCode of
|
||
kbEsc :
|
||
begin
|
||
Close;
|
||
ClearEvent(Event);
|
||
end;
|
||
end;
|
||
evCommand :
|
||
case Event.Command of
|
||
cmTransfer :
|
||
begin
|
||
W:=FirstEditorWindow;
|
||
if Assigned(W) and Assigned(Report) then
|
||
Message(W,evCommand,cmAddChar,pointer(ptrint(ord(Report^.AsciiChar))));
|
||
ClearEvent(Event);
|
||
end;
|
||
cmSearchWindow+1..cmSearchWindow+99 :
|
||
if (Event.Command-cmSearchWindow=Number) then
|
||
ClearEvent(Event);
|
||
end;
|
||
end;
|
||
inherited HandleEvent(Event);
|
||
end;
|
||
|
||
destructor TFPASCIIChart.Done;
|
||
begin
|
||
ASCIIChart:=nil;
|
||
inherited Done;
|
||
end;
|
||
|
||
function TVideoModeListBox.GetText(Item: pointer; MaxLen: sw_integer): string;
|
||
var P: PVideoMode;
|
||
S: string;
|
||
begin
|
||
P:=Item;
|
||
S:=IntToStr(P^.Col)+'x'+IntToStr(P^.Row)+' ';
|
||
if P^.Color then
|
||
S:=S+'color'
|
||
else
|
||
S:=S+'mono';
|
||
GetText:=copy(S,1,MaxLen);
|
||
end;
|
||
|
||
constructor TFPDesktop.Init(var Bounds: TRect);
|
||
begin
|
||
inherited Init(Bounds);
|
||
end;
|
||
|
||
procedure TFPDesktop.InitBackground;
|
||
var AV: PANSIBackground;
|
||
FileName: string;
|
||
R: TRect;
|
||
begin
|
||
AV:=nil;
|
||
FileName:=LocateFile(BackgroundPath);
|
||
if FileName<>'' then
|
||
begin
|
||
GetExtent(R);
|
||
New(AV, Init(R));
|
||
AV^.GrowMode:=gfGrowHiX+gfGrowHiY;
|
||
if AV^.LoadFile(FileName)=false then
|
||
begin
|
||
Dispose(AV, Done); AV:=nil;
|
||
end;
|
||
if Assigned(AV) then
|
||
Insert(AV);
|
||
end;
|
||
Background:=AV;
|
||
if Assigned(Background)=false then
|
||
inherited InitBackground;
|
||
end;
|
||
|
||
constructor TFPDesktop.Load(var S: TStream);
|
||
begin
|
||
inherited Load(S);
|
||
end;
|
||
|
||
procedure TFPDesktop.Store(var S: TStream);
|
||
begin
|
||
inherited Store(S);
|
||
end;
|
||
|
||
constructor TFPToolTip.Init(var Bounds: TRect; const AText: string; AAlign: TAlign);
|
||
begin
|
||
inherited Init(Bounds);
|
||
SetAlign(AAlign);
|
||
SetText(AText);
|
||
end;
|
||
|
||
procedure TFPToolTip.Draw;
|
||
var C: word;
|
||
procedure DrawLine(Y: integer; S: string);
|
||
var B: TDrawBuffer;
|
||
begin
|
||
S:=copy(S,1,Size.X-2);
|
||
case Align of
|
||
alLeft : S:=' '+S;
|
||
alRight : S:=LExpand(' '+S,Size.X);
|
||
alCenter : S:=Center(S,Size.X);
|
||
end;
|
||
MoveChar(B,' ',C,Size.X);
|
||
MoveStr(B,S,C);
|
||
WriteLine(0,Y,Size.X,1,B);
|
||
end;
|
||
var S: string;
|
||
Y: integer;
|
||
begin
|
||
C:=GetColor(1);
|
||
S:=GetText;
|
||
for Y:=0 to Size.Y-1 do
|
||
DrawLine(Y,S);
|
||
end;
|
||
|
||
function TFPToolTip.GetText: string;
|
||
begin
|
||
GetText:=GetStr(Text);
|
||
end;
|
||
|
||
procedure TFPToolTip.SetText(const AText: string);
|
||
begin
|
||
if AText<>GetText then
|
||
begin
|
||
if Assigned(Text) then DisposeStr(Text);
|
||
Text:=NewStr(AText);
|
||
DrawView;
|
||
end;
|
||
end;
|
||
|
||
function TFPToolTip.GetAlign: TAlign;
|
||
begin
|
||
GetAlign:=Align;
|
||
end;
|
||
|
||
procedure TFPToolTip.SetAlign(AAlign: TAlign);
|
||
begin
|
||
if AAlign<>Align then
|
||
begin
|
||
Align:=AAlign;
|
||
DrawView;
|
||
end;
|
||
end;
|
||
|
||
destructor TFPToolTip.Done;
|
||
begin
|
||
if Assigned(Text) then DisposeStr(Text); Text:=nil;
|
||
inherited Done;
|
||
end;
|
||
|
||
function TFPToolTip.GetPalette: PPalette;
|
||
const S: string[length(CFPToolTip)] = CFPToolTip;
|
||
begin
|
||
GetPalette:=@S;
|
||
end;
|
||
|
||
constructor TFPMemo.Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
|
||
PScrollBar; AIndicator: PIndicator);
|
||
begin
|
||
inherited Init(Bounds,AHScrollBar,AVScrollBar,AIndicator,nil);
|
||
SetFlags(Flags and not (efPersistentBlocks) or efSyntaxHighlight);
|
||
end;
|
||
|
||
procedure TFPMemo.HandleEvent(var Event: TEvent);
|
||
var DontClear: boolean;
|
||
S: string;
|
||
begin
|
||
case Event.What of
|
||
evKeyDown :
|
||
begin
|
||
DontClear:=false;
|
||
case Event.KeyCode of
|
||
kbEsc:
|
||
begin
|
||
Event.What:=evCommand;
|
||
Event.Command:=cmCancel;
|
||
PutEvent(Event);
|
||
end;
|
||
else DontClear:=true;
|
||
end;
|
||
if not DontClear then ClearEvent(Event);
|
||
end;
|
||
end;
|
||
inherited HandleEvent(Event);
|
||
end;
|
||
|
||
function TFPMemo.GetPalette: PPalette;
|
||
const P: string[length(CFPMemo)] = CFPMemo;
|
||
begin
|
||
GetPalette:=@P;
|
||
end;
|
||
|
||
function TFPMemo.GetSpecSymbolCount(SpecClass: TSpecSymbolClass): integer;
|
||
begin
|
||
GetSpecSymbolCount:=0;
|
||
end;
|
||
|
||
function TFPMemo.GetSpecSymbol(SpecClass: TSpecSymbolClass; Index: integer): pstring;
|
||
begin
|
||
Abstract;
|
||
GetSpecSymbol:=nil;
|
||
end;
|
||
|
||
function TFPMemo.IsReservedWord(const S: string): boolean;
|
||
begin
|
||
IsReservedWord:=false;
|
||
end;
|
||
|
||
constructor TFPCodeMemo.Init(var Bounds: TRect; AHScrollBar, AVScrollBar:
|
||
PScrollBar; AIndicator: PIndicator);
|
||
begin
|
||
inherited Init(Bounds,AHScrollBar,AVScrollBar,AIndicator);
|
||
end;
|
||
|
||
function TFPCodeMemo.GetSpecSymbolCount(SpecClass: TSpecSymbolClass): integer;
|
||
begin
|
||
GetSpecSymbolCount:=FreePascalSpecSymbolCount[SpecClass];
|
||
end;
|
||
|
||
function TFPCodeMemo.GetSpecSymbol(SpecClass: TSpecSymbolClass; Index: integer): pstring;
|
||
begin
|
||
GetSpecSymbol:=@FreePascalEmptyString;
|
||
case SpecClass of
|
||
ssCommentPrefix :
|
||
case Index of
|
||
0 : GetSpecSymbol:=@FreePascalCommentPrefix1;
|
||
1 : GetSpecSymbol:=@FreePascalCommentPrefix2;
|
||
2 : GetSpecSymbol:=@FreePascalCommentPrefix3;
|
||
end;
|
||
ssCommentSingleLinePrefix :
|
||
case Index of
|
||
0 : GetSpecSymbol:=@FreePascalCommentSingleLinePrefix;
|
||
end;
|
||
ssCommentSuffix :
|
||
case Index of
|
||
0 : GetSpecSymbol:=@FreePascalCommentSuffix1;
|
||
1 : GetSpecSymbol:=@FreePascalCommentSuffix2;
|
||
end;
|
||
ssStringPrefix :
|
||
GetSpecSymbol:=@FreePascalStringPrefix;
|
||
ssStringSuffix :
|
||
GetSpecSymbol:=@FreePascalStringSuffix;
|
||
{ must be uppercased to avoid calling UpCaseStr in MatchesAnyAsmSymbol PM }
|
||
ssAsmPrefix :
|
||
GetSpecSymbol:=@FreePascalAsmPrefix;
|
||
ssAsmSuffix :
|
||
GetSpecSymbol:=@FreePascalAsmSuffix;
|
||
ssDirectivePrefix :
|
||
GetSpecSymbol:=@FreePascalDirectivePrefix;
|
||
ssDirectiveSuffix :
|
||
GetSpecSymbol:=@FreePascalDirectiveSuffix;
|
||
end;
|
||
end;
|
||
|
||
function TFPCodeMemo.IsReservedWord(const S: string): boolean;
|
||
begin
|
||
IsReservedWord:=IsFPReservedWord(S);
|
||
end;
|
||
|
||
|
||
{$ifdef VESA}
|
||
function VESASetVideoModeProc(const VideoMode: TVideoMode; Params: Longint): Boolean;
|
||
begin
|
||
VESASetVideoModeProc:=VESASetMode(Params);
|
||
end;
|
||
|
||
procedure InitVESAScreenModes;
|
||
var ML: TVESAModeList;
|
||
MI: TVESAModeInfoBlock;
|
||
I: integer;
|
||
begin
|
||
if VESAInit=false then Exit;
|
||
if VESAGetModeList(ML)=false then Exit;
|
||
for I:=1 to ML.Count do
|
||
begin
|
||
if VESAGetModeInfo(ML.Modes[I],MI) then
|
||
with MI do
|
||
{$ifndef DEBUG}
|
||
if (Attributes and vesa_vma_GraphicsMode)=0 then
|
||
{$else DEBUG}
|
||
if ((Attributes and vesa_vma_GraphicsMode)=0) or
|
||
{ only allow 4 bit i.e. 16 color modes }
|
||
(((Attributes and vesa_vma_CanBeSetInCurrentConfig)<>0) and
|
||
(BitsPerPixel=8)) then
|
||
{$endif DEBUG}
|
||
RegisterVesaVideoMode(ML.Modes[I]);
|
||
end;
|
||
end;
|
||
|
||
procedure DoneVESAScreenModes;
|
||
begin
|
||
FreeVesaModes;
|
||
end;
|
||
{$endif}
|
||
|
||
procedure NoDebugger;
|
||
begin
|
||
InformationBox(msg_nodebuggersupportavailable,nil);
|
||
end;
|
||
|
||
procedure RegisterFPViews;
|
||
begin
|
||
RegisterType(RSourceEditor);
|
||
RegisterType(RSourceWindow);
|
||
RegisterType(RFPHelpViewer);
|
||
RegisterType(RFPHelpWindow);
|
||
RegisterType(RClipboardWindow);
|
||
RegisterType(RMessageListBox);
|
||
RegisterType(RFPDesktop);
|
||
RegisterType(RFPASCIIChart);
|
||
RegisterType(RFPDlgWindow);
|
||
{$ifndef NODEBUG}
|
||
RegisterType(RGDBWindow);
|
||
RegisterType(RGDBSourceEditor);
|
||
{$endif NODEBUG}
|
||
end;
|
||
|
||
|
||
END.
|