mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-05 10:57:55 +02:00
1622 lines
49 KiB
ObjectPascal
1622 lines
49 KiB
ObjectPascal
{
|
|
***************************************************************************
|
|
* *
|
|
* This source is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This code 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. See the GNU *
|
|
* General Public License for more details. *
|
|
* *
|
|
* A copy of the GNU General Public License is available on the World *
|
|
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
|
|
* obtain it by writing to the Free Software Foundation, *
|
|
* Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. *
|
|
* *
|
|
***************************************************************************
|
|
|
|
see for todo list: http://wiki.lazarus.freepascal.org/index.php/LazDoc
|
|
}
|
|
|
|
unit FPDocEditWindow;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
{off $define VerboseCodeHelp}
|
|
|
|
interface
|
|
|
|
uses
|
|
// FCL
|
|
Classes, SysUtils,
|
|
// LazUtils
|
|
Laz2_DOM, Laz2_XMLRead, LazStringUtils, LazTracer,
|
|
// LCL
|
|
LResources, StdCtrls, Buttons, ComCtrls, Controls, Dialogs,
|
|
ExtCtrls, Forms, Graphics, LCLType, LCLProc,
|
|
// Synedit
|
|
SynEdit, SynHighlighterXML, SynEditFoldedView, SynEditWrappedView,
|
|
// codetools
|
|
FileProcs, CodeCache, CodeToolManager, CTXMLFixFragment,
|
|
// IDEIntf
|
|
IDEWindowIntf, LazIDEIntf, Menus,
|
|
SrcEditorIntf, IDEDialogs, LazFileUtils, IDEImagesIntf,
|
|
// IdeUtils
|
|
IdeUtilsPkgStrConsts,
|
|
// IDE
|
|
IDEOptionDefs, EnvironmentOpts, LazarusIDEStrConsts,
|
|
FPDocSelectInherited, FPDocSelectLink, CodeHelp;
|
|
|
|
type
|
|
TFPDocEditorFlag = (
|
|
fpdefReading,
|
|
fpdefWriting,
|
|
fpdefCodeCacheNeedsUpdate,
|
|
fpdefChainNeedsUpdate,
|
|
fpdefCaptionNeedsUpdate,
|
|
fpdefValueControlsNeedsUpdate,
|
|
fpdefInheritedControlsNeedsUpdate,
|
|
fpdefTopicSettingUp,
|
|
fpdefTopicNeedsUpdate,
|
|
fpdefWasHidden
|
|
);
|
|
TFPDocEditorFlags = set of TFPDocEditorFlag;
|
|
|
|
{ TFPDocEditor }
|
|
|
|
TFPDocEditor = class(TForm)
|
|
AddLinkToInheritedButton: TButton;
|
|
BoldFormatButton: TSpeedButton;
|
|
BrowseExampleButton: TButton;
|
|
OpenXMLButton: TButton;
|
|
ShortPanel: TPanel;
|
|
DescrShortEdit: TEdit;
|
|
SynXMLSyn1: TSynXMLSyn;
|
|
TopicShort: TEdit;
|
|
TopicDescrSynEdit: TSynEdit;
|
|
Panel3: TPanel;
|
|
TopicListBox: TListBox;
|
|
NewTopicNameEdit: TEdit;
|
|
NewTopicButton: TButton;
|
|
CopyFromInheritedButton: TButton;
|
|
CreateButton: TButton;
|
|
DescrSynEdit: TSynEdit;
|
|
DescrTabSheet: TTabSheet;
|
|
ErrorsSynEdit: TSynEdit;
|
|
ErrorsTabSheet: TTabSheet;
|
|
ExampleEdit: TEdit;
|
|
ExampleTabSheet: TTabSheet;
|
|
InheritedShortEdit: TEdit;
|
|
InheritedShortLabel: TLabel;
|
|
InheritedTabSheet: TTabSheet;
|
|
InsertCodeTagButton: TSpeedButton;
|
|
InsertLinkSpeedButton: TSpeedButton;
|
|
InsertParagraphSpeedButton: TSpeedButton;
|
|
InsertRemarkButton: TSpeedButton;
|
|
InsertVarTagButton: TSpeedButton;
|
|
ItalicFormatButton: TSpeedButton;
|
|
LeftBtnPanel: TPanel;
|
|
LinkEdit: TEdit;
|
|
LinkLabel: TLabel;
|
|
Panel1: TPanel;
|
|
Panel2: TPanel;
|
|
SaveButton: TSpeedButton;
|
|
SeeAlsoSynEdit: TSynEdit;
|
|
MoveToInheritedButton: TButton;
|
|
OpenDialog: TOpenDialog;
|
|
PageControl: TPageControl;
|
|
SeeAlsoTabSheet: TTabSheet;
|
|
ShortEdit: TEdit;
|
|
ShortLabel: TLabel;
|
|
ShortTabSheet: TTabSheet;
|
|
InsertPrintShortSpeedButton: TSpeedButton;
|
|
InsertURLTagSpeedButton: TSpeedButton;
|
|
TopicSheet: TTabSheet;
|
|
UnderlineFormatButton: TSpeedButton;
|
|
procedure AddLinkToInheritedButtonClick(Sender: TObject);
|
|
procedure ApplicationIdle(Sender: TObject; var Done: Boolean);
|
|
procedure BrowseExampleButtonClick(Sender: TObject);
|
|
procedure CopyFromInheritedButtonClick(Sender: TObject);
|
|
procedure CopyShortToDescrMenuItemClick(Sender: TObject);
|
|
procedure CreateButtonClick(Sender: TObject);
|
|
procedure DescrSynEditChange(Sender: TObject);
|
|
procedure ErrorsSynEditChange(Sender: TObject);
|
|
procedure ExampleEditChange(Sender: TObject);
|
|
procedure FormatButtonClick(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure FormDestroy(Sender: TObject);
|
|
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
|
procedure FormShow(Sender: TObject);
|
|
procedure InsertLinkSpeedButtonClick(Sender: TObject);
|
|
procedure LinkEditChange(Sender: TObject);
|
|
procedure MoveToInheritedButtonClick(Sender: TObject);
|
|
procedure NewTopicButtonClick(Sender: TObject);
|
|
procedure OpenXMLButtonClick(Sender: TObject);
|
|
procedure PageControlChange(Sender: TObject);
|
|
procedure SaveButtonClick(Sender: TObject);
|
|
procedure SeeAlsoSynEditChange(Sender: TObject);
|
|
procedure ShortEditChange(Sender: TObject);
|
|
procedure TopicControlEnter(Sender: TObject);
|
|
procedure TopicDescrSynEditChange(Sender: TObject);
|
|
procedure TopicListBoxClick(Sender: TObject);
|
|
private
|
|
FCaretXY: TPoint;
|
|
FModified: Boolean;
|
|
FFlags: TFPDocEditorFlags;
|
|
fUpdateLock: Integer;
|
|
fSourceFilename: string;
|
|
fDocFile: TLazFPDocFile;
|
|
fChain: TCodeHelpElementChain;
|
|
FOldValues: TFPDocElementValues;
|
|
FOldVisualValues: TFPDocElementValues;
|
|
function GetDoc: TXMLdocument;
|
|
function GetDocFile: TLazFPDocFile;
|
|
function GetSourceFilename: string;
|
|
function GetFirstElement: TDOMNode;
|
|
|
|
function GetContextTitle(Element: TCodeHelpElement): string;
|
|
|
|
function FindInheritedIndex: integer;
|
|
procedure Save(CheckGUI: boolean = false);
|
|
function GetGUIValues: TFPDocElementValues;
|
|
procedure SetModified(const AValue: boolean);
|
|
function WriteNode(Element: TCodeHelpElement; Values: TFPDocElementValues;
|
|
Interactive: Boolean): Boolean;
|
|
procedure UpdateCodeCache;
|
|
procedure UpdateChain;
|
|
procedure UpdateCaption;
|
|
procedure UpdateValueControls;
|
|
procedure UpdateInheritedControls;
|
|
procedure OnFPDocChanging(Sender: TObject; FPDocFPFile: TLazFPDocFile);
|
|
procedure OnFPDocChanged(Sender: TObject; FPDocFPFile: TLazFPDocFile);
|
|
procedure LoadGUIValues(Element: TCodeHelpElement);
|
|
procedure MoveToInherited(Element: TCodeHelpElement);
|
|
function GetDefaultDocFile(CreateIfNotExists: Boolean = False): TLazFPDocFile;
|
|
function ExtractIDFromLinkTag(const LinkTag: string; out ID, Title: string): boolean;
|
|
function CreateElement(Element: TCodeHelpElement): Boolean;
|
|
procedure UpdateButtons;
|
|
function GetCurrentUnitName: string;
|
|
function GetCurrentOwnerName: string;
|
|
procedure JumpToError(Item : TFPDocItem; LineCol: TPoint);
|
|
procedure OpenXML;
|
|
function GUIModified: boolean;
|
|
procedure DoEditorUpdate(Sender: TObject);
|
|
procedure DoEditorMouseUp(Sender: TObject);
|
|
private
|
|
FFollowCursor: boolean;
|
|
FIdleConnected: boolean;
|
|
FLastTopicControl: TControl;
|
|
FCurrentTopic: String;
|
|
procedure SetFollowCursor(AValue: boolean);
|
|
procedure SetIdleConnected(AValue: boolean);
|
|
procedure UpdateTopicCombo;
|
|
procedure ClearTopicControls;
|
|
procedure UpdateTopic;
|
|
protected
|
|
procedure UpdateShowing; override;
|
|
procedure Loaded; override;
|
|
public
|
|
procedure Reset;
|
|
procedure InvalidateChain;
|
|
procedure LoadIdentifierAt(const SrcFilename: string; const Caret: TPoint);
|
|
procedure LoadIdentifierAtCursor;
|
|
procedure BeginUpdate;
|
|
procedure EndUpdate;
|
|
procedure ClearEntry(DoSave: Boolean);
|
|
property DocFile: TLazFPDocFile read GetDocFile;
|
|
property Doc: TXMLdocument read GetDoc;
|
|
property SourceFilename: string read GetSourceFilename;
|
|
property CaretXY: TPoint read FCaretXY;
|
|
property Modified: boolean read FModified write SetModified;
|
|
property IdleConnected: boolean read FIdleConnected write SetIdleConnected;
|
|
property FollowCursor: boolean read FFollowCursor write SetFollowCursor;
|
|
end;
|
|
|
|
var
|
|
FPDocEditor: TFPDocEditor = nil;
|
|
|
|
procedure DoShowFPDocEditor(State: TIWGetFormState = iwgfShowOnTop);
|
|
|
|
implementation
|
|
|
|
{$R *.lfm}
|
|
{$R lazdoc.res}
|
|
|
|
{ TFPDocEditor }
|
|
|
|
procedure DoShowFPDocEditor(State: TIWGetFormState);
|
|
begin
|
|
if FPDocEditor = Nil then
|
|
IDEWindowCreators.CreateForm(FPDocEditor,TFPDocEditor,
|
|
State=iwgfDisabled,LazarusIDE.OwningComponent)
|
|
else if State=iwgfDisabled then
|
|
FPDocEditor.DisableAutoSizing{$IFDEF DebugDisableAutoSizing}('DoShowFPDocEditor'){$ENDIF};
|
|
|
|
if State>=iwgfShow then
|
|
IDEWindowCreators.ShowForm(FPDocEditor,State=iwgfShowOnTop);
|
|
end;
|
|
|
|
function TFPDocEditor.GetFirstElement: TDOMNode;
|
|
var
|
|
CurDocFile: TLazFPDocFile;
|
|
begin
|
|
Result:=nil;
|
|
CurDocFile:=DocFile;
|
|
if CurDocFile=nil then exit;
|
|
Result:=CurDocFile.GetFirstElement;
|
|
end;
|
|
|
|
procedure TFPDocEditor.FormCreate(Sender: TObject);
|
|
procedure UpdateSynEdit(ASynEd: TSynEdit);
|
|
var
|
|
fld: TSynEditFoldedView;
|
|
begin
|
|
fld := TSynEditFoldedView(ASynEd.TextViewsManager.SynTextViewByClass[TSynEditFoldedView]);
|
|
if fld <> nil then
|
|
fld.FoldProvider.Enabled := False;
|
|
TLazSynEditLineWrapPlugin.Create(ASynEd);
|
|
end;
|
|
begin
|
|
Caption := lisCodeHelpMainFormCaption;
|
|
|
|
ShortTabSheet.Caption := lisCodeHelpShortTag;
|
|
InheritedTabSheet.Caption := lisCodeHelpInherited;
|
|
DescrTabSheet.Caption := lisCodeHelpDescrTag;
|
|
ErrorsTabSheet.Caption := lisCodeHelpErrorsTag;
|
|
SeeAlsoTabSheet.Caption := lisCodeHelpSeeAlsoTag;
|
|
ExampleTabSheet.Caption := lisCodeHelpExampleTag;
|
|
|
|
PageControl.PageIndex := 0;
|
|
|
|
BoldFormatButton.Hint := lisCodeHelpHintBoldFormat;
|
|
ItalicFormatButton.Hint := lisCodeHelpHintItalicFormat;
|
|
UnderlineFormatButton.Hint := lisCodeHelpHintUnderlineFormat;
|
|
InsertCodeTagButton.Hint := lisCodeHelpHintInsertCodeTag;
|
|
InsertRemarkButton.Hint := lisCodeHelpHintRemarkTag;
|
|
InsertVarTagButton.Hint := lisCodeHelpHintVarTag;
|
|
InsertParagraphSpeedButton.Hint := lisCodeHelpInsertParagraphFormattingTag;
|
|
InsertLinkSpeedButton.Hint := lisCodeHelpInsertALink;
|
|
InsertPrintShortSpeedButton.Hint:=lisInsertPrintshortTag2;
|
|
InsertURLTagSpeedButton.Hint:=lisInsertUrlTag;
|
|
|
|
ShortLabel.Caption:=lisShort;
|
|
LinkLabel.Caption:=lisLink;
|
|
CreateButton.Caption := lisCodeHelpCreateButton;
|
|
OpenXMLButton.Caption:=lisOpenXML;
|
|
OpenXMLButton.Enabled:=false;
|
|
SaveButton.Caption := '';
|
|
SaveButton.Enabled:=false;
|
|
SaveButton.Hint:=lisSave;
|
|
SaveButton.ShowHint:=true;
|
|
|
|
BrowseExampleButton.Caption := lisCodeHelpBrowseExampleButton;
|
|
|
|
MoveToInheritedButton.Caption:=lisLDMoveEntriesToInherited;
|
|
CopyFromInheritedButton.Caption:=lisLDCopyFromInherited;
|
|
AddLinkToInheritedButton.Caption:=lisLDAddLinkToInherited;
|
|
|
|
Reset;
|
|
|
|
CodeHelpBoss.AddHandlerOnChanging(@OnFPDocChanging);
|
|
CodeHelpBoss.AddHandlerOnChanged(@OnFPDocChanged);
|
|
|
|
Name := NonModalIDEWindowNames[nmiwFPDocEditor];
|
|
|
|
IDEImages.AssignImage(BoldFormatButton, 'formatbold');
|
|
IDEImages.AssignImage(UnderlineFormatButton, 'formatunderline');
|
|
IDEImages.AssignImage(ItalicFormatButton, 'formatitalic');
|
|
IDEImages.AssignImage(InsertVarTagButton, 'insertvartag');
|
|
IDEImages.AssignImage(InsertCodeTagButton, 'insertcodetag');
|
|
IDEImages.AssignImage(InsertRemarkButton, 'insertremark');
|
|
IDEImages.AssignImage(InsertURLTagSpeedButton, 'inserturltag');
|
|
IDEImages.AssignImage(InsertLinkSpeedButton, 'insertlink');
|
|
IDEImages.AssignImage(InsertParagraphSpeedButton, 'insertparagraph');
|
|
IDEImages.AssignImage(InsertPrintShortSpeedButton, 'insertprintshort');
|
|
IDEImages.AssignImage(SaveButton, 'laz_save');
|
|
|
|
SourceEditorManagerIntf.RegisterChangeEvent(semEditorActivate, @DoEditorUpdate);
|
|
SourceEditorManagerIntf.RegisterChangeEvent(semEditorStatus, @DoEditorUpdate);
|
|
SourceEditorManagerIntf.RegisterChangeEvent(semEditorMouseUp, @DoEditorMouseUp);
|
|
|
|
UpdateSynEdit(TopicDescrSynEdit);
|
|
UpdateSynEdit(DescrSynEdit);
|
|
UpdateSynEdit(ErrorsSynEdit);
|
|
UpdateSynEdit(SeeAlsoSynEdit);
|
|
|
|
FollowCursor:=true;
|
|
IdleConnected:=true;
|
|
end;
|
|
|
|
procedure TFPDocEditor.FormDestroy(Sender: TObject);
|
|
begin
|
|
IdleConnected:=false;
|
|
Reset;
|
|
FreeAndNil(fChain);
|
|
if assigned(CodeHelpBoss) then
|
|
CodeHelpBoss.RemoveAllHandlersOfObject(Self);
|
|
Application.RemoveAllHandlersOfObject(Self);
|
|
if SourceEditorManagerIntf<>nil then begin
|
|
SourceEditorManagerIntf.UnRegisterChangeEvent(semEditorActivate, @DoEditorUpdate);
|
|
SourceEditorManagerIntf.UnRegisterChangeEvent(semEditorStatus, @DoEditorUpdate);
|
|
end;
|
|
end;
|
|
|
|
procedure TFPDocEditor.FormKeyDown(Sender: TObject; var Key: Word;
|
|
Shift: TShiftState);
|
|
begin
|
|
if (Key=VK_S) and (Shift=[ssCtrl]) then begin
|
|
Save(true);
|
|
Key:=VK_UNKNOWN;
|
|
end;
|
|
end;
|
|
|
|
procedure TFPDocEditor.FormShow(Sender: TObject);
|
|
begin
|
|
DoEditorUpdate(nil);
|
|
end;
|
|
|
|
procedure TFPDocEditor.FormatButtonClick(Sender: TObject);
|
|
|
|
procedure InsertTag(const StartTag, EndTag: String);
|
|
begin
|
|
if PageControl.ActivePage = ShortTabSheet then begin
|
|
ShortEdit.SelText := StartTag + ShortEdit.SelText + EndTag;
|
|
DescrShortEdit.Text:=ShortEdit.Text;
|
|
end else if PageControl.ActivePage = DescrTabSheet then
|
|
DescrSynEdit.SelText := StartTag + DescrSynEdit.SelText + EndTag
|
|
else if PageControl.ActivePage = ErrorsTabSheet then
|
|
ErrorsSynEdit.SelText := StartTag + ErrorsSynEdit.SelText + EndTag
|
|
else if PageControl.ActivePage = TopicSheet then begin
|
|
if (FLastTopicControl = TopicShort) then
|
|
TopicShort.SelText := StartTag + TopicShort.SelText + EndTag;
|
|
if (FLastTopicControl = TopicDescrSynEdit) then
|
|
TopicDescrSynEdit.SelText := StartTag + TopicDescrSynEdit.SelText + EndTag;
|
|
end
|
|
else
|
|
exit;
|
|
Modified:=true;
|
|
end;
|
|
|
|
begin
|
|
case TSpeedButton(Sender).Tag of
|
|
//bold
|
|
0:
|
|
InsertTag('<b>', '</b>');
|
|
//italic
|
|
1:
|
|
InsertTag('<i>', '</i>');
|
|
//underline
|
|
2:
|
|
InsertTag('<u>', '</u>');
|
|
//code tag
|
|
3:
|
|
InsertTag('<p><code>', '</code></p>');
|
|
//remark tag
|
|
4:
|
|
InsertTag('<p><remark>', '</remark></p>');
|
|
//var tag
|
|
5:
|
|
InsertTag('<var>', '</var>');
|
|
//paragraph tag
|
|
6:
|
|
InsertTag('<p>', '</p>');
|
|
//printshort
|
|
7:
|
|
if (fChain<>nil) and (fChain.Count>0) then
|
|
InsertTag('<printshort id="'+fChain[0].ElementName+'"/>','');
|
|
//url tag
|
|
8:
|
|
InsertTag('<url href="">', '</url>');
|
|
end;
|
|
end;
|
|
|
|
procedure TFPDocEditor.InsertLinkSpeedButtonClick(Sender: TObject);
|
|
var
|
|
Link: string;
|
|
LinkTitle: string;
|
|
LinkSrc: String;
|
|
begin
|
|
if ShowFPDocLinkEditorDialog(fSourceFilename,DocFile,Link,LinkTitle)<>mrOk then exit;
|
|
if Link='' then exit;
|
|
LinkSrc:='<link id="'+Link+'"';
|
|
if LinkTitle='' then begin
|
|
LinkSrc:=LinkSrc+'/>';
|
|
end else begin
|
|
LinkSrc:=LinkSrc+'>'+LinkTitle+'</link>';
|
|
end;
|
|
if PageControl.ActivePage = ShortTabSheet then begin
|
|
ShortEdit.SelText := LinkSrc;
|
|
DescrShortEdit.Text := ShortEdit.Text;
|
|
end;
|
|
if PageControl.ActivePage = DescrTabSheet then
|
|
DescrSynEdit.SelText := LinkSrc;
|
|
if PageControl.ActivePage = SeeAlsoTabSheet then
|
|
SeeAlsoSynEdit.SelText := LinkSrc;
|
|
if PageControl.ActivePage = ErrorsTabSheet then
|
|
ErrorsSynEdit.SelText := LinkSrc;
|
|
if PageControl.ActivePage = TopicSheet then begin
|
|
if (FLastTopicControl = TopicShort) then
|
|
TopicShort.SelText := LinkSrc;
|
|
if (FLastTopicControl = TopicDescrSynEdit) then
|
|
TopicDescrSynEdit.SelText := LinkSrc;
|
|
end;
|
|
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TFPDocEditor.LinkEditChange(Sender: TObject);
|
|
begin
|
|
if fpdefReading in FFlags then exit;
|
|
if LinkEdit.Text<>FOldVisualValues[fpdiElementLink] then
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TFPDocEditor.ApplicationIdle(Sender: TObject; var Done: Boolean);
|
|
var
|
|
ActiveForm: TCustomForm;
|
|
begin
|
|
if (fUpdateLock>0) then
|
|
begin
|
|
DebugLn(['WARNING: TFPDocEditor.ApplicationIdle fUpdateLock>0']);
|
|
exit;
|
|
end;
|
|
if not IsVisible then begin
|
|
Include(FFlags,fpdefWasHidden);
|
|
IdleConnected:=false;
|
|
exit;
|
|
end;
|
|
ActiveForm:=Screen.ActiveCustomForm;
|
|
if (ActiveForm<>nil) and (fsModal in ActiveForm.FormState) then exit;
|
|
Done:=false;
|
|
if fpdefCodeCacheNeedsUpdate in FFlags then
|
|
UpdateCodeCache
|
|
else if fpdefChainNeedsUpdate in FFlags then
|
|
UpdateChain
|
|
else if fpdefCaptionNeedsUpdate in FFlags then
|
|
UpdateCaption
|
|
else if fpdefValueControlsNeedsUpdate in FFlags then
|
|
UpdateValueControls
|
|
else if fpdefInheritedControlsNeedsUpdate in FFlags then
|
|
UpdateInheritedControls
|
|
else if fpdefTopicNeedsUpdate in FFlags then
|
|
UpdateTopicCombo
|
|
else begin
|
|
//debugln(['TFPDocEditor.ApplicationIdle updated']);
|
|
Done:=true;
|
|
IdleConnected:=false;
|
|
end;
|
|
end;
|
|
|
|
procedure TFPDocEditor.MoveToInheritedButtonClick(Sender: TObject);
|
|
var
|
|
i: Integer;
|
|
Element: TCodeHelpElement;
|
|
Candidates: TFPList;
|
|
FPDocSelectInheritedDlg: TFPDocSelectInheritedDlg;
|
|
ShortDescr: String;
|
|
begin
|
|
if fChain=nil then exit;
|
|
Candidates:=nil;
|
|
FPDocSelectInheritedDlg:=nil;
|
|
try
|
|
// find all entries till the first inherited entry with a description
|
|
for i:=1 to fChain.Count-1 do begin
|
|
Element:=fChain[i];
|
|
if Candidates=nil then
|
|
Candidates:=TFPList.Create;
|
|
Candidates.Add(Element);
|
|
if (Element.ElementNode<>nil)
|
|
and (Element.FPDocFile.GetValueFromNode(Element.ElementNode,fpdiShort)<>'')
|
|
then
|
|
break;
|
|
end;
|
|
|
|
// choose one entry
|
|
if (Candidates=nil) or (Candidates.Count=0) then exit;
|
|
if Candidates.Count=1 then begin
|
|
// there is only one candidate
|
|
Element:=TCodeHelpElement(Candidates[0]);
|
|
if (Element.ElementNode<>nil) then begin
|
|
ShortDescr:=Element.FPDocFile.GetValueFromNode(Element.ElementNode,fpdiShort);
|
|
if ShortDescr<>'' then begin
|
|
// the inherited entry already contains a description.
|
|
// ask if it should be really replaced
|
|
if IDEQuestionDialog(lisCodeHelpConfirmreplace,
|
|
GetContextTitle(Element)+' already contains the help:'+LineEnding+ShortDescr,
|
|
mtConfirmation, [mrYes, lisReplace,
|
|
mrCancel]) <> mrYes then exit;
|
|
end;
|
|
end;
|
|
end else begin
|
|
// there is more than one candidate
|
|
// => ask which one to replace
|
|
FPDocSelectInheritedDlg:=TFPDocSelectInheritedDlg.Create(nil);
|
|
FPDocSelectInheritedDlg.InheritedComboBox.Items.Clear;
|
|
for i:=0 to Candidates.Count-1 do begin
|
|
Element:=TCodeHelpElement(Candidates[i]);
|
|
FPDocSelectInheritedDlg.InheritedComboBox.Items.Add(
|
|
GetContextTitle(Element));
|
|
end;
|
|
if FPDocSelectInheritedDlg.ShowModal<>mrOk then exit;
|
|
i:=FPDocSelectInheritedDlg.InheritedComboBox.ItemIndex;
|
|
if i<0 then exit;
|
|
Element:=TCodeHelpElement(Candidates[i]);
|
|
end;
|
|
|
|
// move the content of the current entry to the inherited entry
|
|
MoveToInherited(Element);
|
|
finally
|
|
FPDocSelectInheritedDlg.Free;
|
|
Candidates.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TFPDocEditor.NewTopicButtonClick(Sender: TObject);
|
|
var
|
|
Dfile: TLazFPDocFile;
|
|
begin
|
|
if NewTopicNameEdit.Text = '' then exit;
|
|
Dfile := GetDefaultDocFile(True);
|
|
if not assigned(DFile) then exit;
|
|
if DFile.GetModuleTopic(NewTopicNameEdit.Text) = nil then begin
|
|
DFile.CreateModuleTopic(NewTopicNameEdit.Text);
|
|
CodeHelpBoss.SaveFPDocFile(DFile);
|
|
end;
|
|
UpdateTopicCombo;
|
|
TopicListBox.ItemIndex := TopicListBox.Items.IndexOf(NewTopicNameEdit.Text);
|
|
TopicListBoxClick(Sender);
|
|
end;
|
|
|
|
procedure TFPDocEditor.OpenXMLButtonClick(Sender: TObject);
|
|
begin
|
|
OpenXML;
|
|
end;
|
|
|
|
procedure TFPDocEditor.PageControlChange(Sender: TObject);
|
|
begin
|
|
UpdateButtons;
|
|
end;
|
|
|
|
procedure TFPDocEditor.SaveButtonClick(Sender: TObject);
|
|
begin
|
|
Save;
|
|
UpdateValueControls;
|
|
end;
|
|
|
|
procedure TFPDocEditor.SeeAlsoSynEditChange(Sender: TObject);
|
|
begin
|
|
if fpdefReading in FFlags then exit;
|
|
if SeeAlsoSynEdit.Text<>FOldVisualValues[fpdiSeeAlso] then
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TFPDocEditor.ShortEditChange(Sender: TObject);
|
|
// called by ShortEdit and DescrShortEdit
|
|
var
|
|
NewShort: String;
|
|
begin
|
|
if fpdefReading in FFlags then exit;
|
|
//debugln(['TFPDocEditor.ShortEditChange ',DbgSName(Sender)]);
|
|
if Sender=DescrShortEdit then
|
|
NewShort:=DescrShortEdit.Text
|
|
else
|
|
NewShort:=ShortEdit.Text;
|
|
if NewShort<>FOldVisualValues[fpdiShort] then
|
|
Modified:=true;
|
|
// copy to the other edit
|
|
if Sender=DescrShortEdit then
|
|
ShortEdit.Text:=NewShort
|
|
else
|
|
DescrShortEdit.Text:=NewShort;
|
|
end;
|
|
|
|
procedure TFPDocEditor.TopicControlEnter(Sender: TObject);
|
|
begin
|
|
FLastTopicControl := TControl(Sender);
|
|
end;
|
|
|
|
procedure TFPDocEditor.TopicDescrSynEditChange(Sender: TObject);
|
|
begin
|
|
if fpdefReading in FFlags then exit;
|
|
if fpdefTopicSettingUp in FFlags then exit;
|
|
Modified := True;
|
|
end;
|
|
|
|
procedure TFPDocEditor.TopicListBoxClick(Sender: TObject);
|
|
begin
|
|
if fpdefTopicSettingUp in FFlags then exit;
|
|
if (FCurrentTopic <> '') and Modified then
|
|
Save;
|
|
UpdateTopic;
|
|
end;
|
|
|
|
function TFPDocEditor.GetContextTitle(Element: TCodeHelpElement): string;
|
|
// get codetools path. for example: TButton.Align
|
|
begin
|
|
Result:='';
|
|
if Element=nil then exit;
|
|
Result:=Element.ElementName;
|
|
end;
|
|
|
|
function TFPDocEditor.GetDoc: TXMLdocument;
|
|
begin
|
|
if DocFile<>nil then
|
|
Result:=DocFile.Doc
|
|
else
|
|
Result:=nil;
|
|
end;
|
|
|
|
procedure TFPDocEditor.ClearTopicControls;
|
|
var
|
|
OldSettingUp: boolean;
|
|
begin
|
|
OldSettingUp:=fpdefTopicSettingUp in FFlags;
|
|
Include(FFlags, fpdefTopicSettingUp);
|
|
try
|
|
TopicShort.Clear;
|
|
TopicDescrSynEdit.Clear;
|
|
TopicShort.Enabled := False;
|
|
TopicDescrSynEdit.Enabled := False;
|
|
finally
|
|
if not OldSettingUp then
|
|
Exclude(FFlags, fpdefTopicSettingUp);
|
|
end;
|
|
end;
|
|
|
|
function TFPDocEditor.GetDocFile: TLazFPDocFile;
|
|
begin
|
|
Result:=nil;
|
|
if fChain<>nil then
|
|
Result:=fChain.DocFile
|
|
else
|
|
Result:=fDocFile;
|
|
end;
|
|
|
|
function TFPDocEditor.GetSourceFilename: string;
|
|
begin
|
|
Result:=fSourceFilename;
|
|
end;
|
|
|
|
procedure TFPDocEditor.UpdateCaption;
|
|
var
|
|
strCaption: String;
|
|
Filename: String;
|
|
begin
|
|
if fUpdateLock>0 then begin
|
|
Include(FFlags,fpdefCaptionNeedsUpdate);
|
|
exit;
|
|
end;
|
|
Exclude(FFlags,fpdefCaptionNeedsUpdate);
|
|
|
|
{$IFDEF VerboseCodeHelp}
|
|
DebugLn(['TFPDocEditForm.UpdateCaption START']);
|
|
{$ENDIF}
|
|
strCaption := lisCodeHelpMainFormCaption + ' - ';
|
|
|
|
if (fChain <> nil) and (fChain.Count>0) then
|
|
strCaption := strCaption + GetContextTitle(fChain[0]) + ' - '
|
|
else
|
|
strCaption := strCaption + lisCodeHelpNoTagCaption + ' - ';
|
|
|
|
if DocFile<>nil then begin
|
|
Filename:=DocFile.Filename;
|
|
if (LazarusIDE.ActiveProject<>nil) then
|
|
Filename:=LazarusIDE.ActiveProject.GetShortFilename(Filename,true);
|
|
Caption := strCaption + Filename;
|
|
end else
|
|
Caption := strCaption + lisCodeHelpNoTagCaption;
|
|
{$IFDEF VerboseCodeHelp}
|
|
DebugLn(['TFPDocEditor.UpdateCaption ',Caption]);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TFPDocEditor.UpdateValueControls;
|
|
var
|
|
Element: TCodeHelpElement;
|
|
begin
|
|
if fUpdateLock>0 then begin
|
|
Include(FFlags,fpdefValueControlsNeedsUpdate);
|
|
exit;
|
|
end;
|
|
Exclude(FFlags,fpdefValueControlsNeedsUpdate);
|
|
|
|
{$IFDEF VerboseCodeHelp}
|
|
DebugLn(['TFPDocEditForm.UpdateValueControls START']);
|
|
{$ENDIF}
|
|
Element:=nil;
|
|
if (fChain<>nil) and (fChain.Count>0) then
|
|
Element:=fChain[0];
|
|
LoadGUIValues(Element);
|
|
SaveButton.Enabled:=FModified;
|
|
end;
|
|
|
|
procedure TFPDocEditor.UpdateInheritedControls;
|
|
var
|
|
i: LongInt;
|
|
Element: TCodeHelpElement;
|
|
ShortDescr: String;
|
|
begin
|
|
if fUpdateLock>0 then begin
|
|
Include(FFlags,fpdefInheritedControlsNeedsUpdate);
|
|
exit;
|
|
end;
|
|
Exclude(FFlags,fpdefInheritedControlsNeedsUpdate);
|
|
|
|
{$IFDEF VerboseCodeHelp}
|
|
DebugLn(['TFPDocEditForm.UpdateInheritedControls START']);
|
|
{$ENDIF}
|
|
i:=FindInheritedIndex;
|
|
if i<0 then begin
|
|
InheritedShortEdit.Text:='';
|
|
InheritedShortEdit.Enabled:=false;
|
|
InheritedShortLabel.Caption:=lisCodeHelpnoinheriteddescriptionfound;
|
|
end else begin
|
|
Element:=fChain[i];
|
|
ShortDescr:=Element.FPDocFile.GetValueFromNode(Element.ElementNode,fpdiShort);
|
|
InheritedShortEdit.Text:=ShortDescr;
|
|
InheritedShortEdit.Enabled:=true;
|
|
InheritedShortLabel.Caption:=lisCodeHelpShortdescriptionOf+' '
|
|
+GetContextTitle(Element);
|
|
end;
|
|
MoveToInheritedButton.Enabled:=(fChain<>nil)
|
|
and (fChain.Count>1)
|
|
and (ShortEdit.Text<>'');
|
|
CopyFromInheritedButton.Enabled:=(i>=0);
|
|
AddLinkToInheritedButton.Enabled:=(i>=0);
|
|
end;
|
|
|
|
procedure TFPDocEditor.UpdateChain;
|
|
var
|
|
Code: TCodeBuffer;
|
|
LDResult: TCodeHelpParseResult;
|
|
NewChain: TCodeHelpElementChain;
|
|
CacheWasUsed: Boolean;
|
|
begin
|
|
fDocFile:=nil;
|
|
FreeAndNil(fChain);
|
|
if fUpdateLock>0 then begin
|
|
Include(FFlags,fpdefChainNeedsUpdate);
|
|
exit;
|
|
end;
|
|
Exclude(FFlags,fpdefChainNeedsUpdate);
|
|
|
|
if (fSourceFilename='') or (CaretXY.X<1) or (CaretXY.Y<1) then exit;
|
|
|
|
{$IFDEF VerboseCodeHelp}
|
|
DebugLn(['TFPDocEditForm.UpdateChain START ',fSourceFilename,' ',dbgs(CaretXY)]);
|
|
{$ENDIF}
|
|
NewChain:=nil;
|
|
try
|
|
// fetch pascal source
|
|
Code:=CodeToolBoss.LoadFile(fSourceFilename,true,false);
|
|
if Code=nil then begin
|
|
DebugLn(['TFPDocEditForm.UpdateChain failed loading ',fSourceFilename]);
|
|
exit;
|
|
end;
|
|
|
|
// start getting the fpdoc element chain
|
|
LDResult:=CodeHelpBoss.GetElementChain(Code,CaretXY.X,CaretXY.Y,true,
|
|
NewChain,CacheWasUsed);
|
|
case LDResult of
|
|
chprParsing:
|
|
begin
|
|
Include(FFlags,fpdefChainNeedsUpdate);
|
|
DebugLn(['TFPDocEditForm.UpdateChain ToDo: still parsing CodeHelpBoss.GetElementChain for ',fSourceFilename,' ',dbgs(CaretXY)]);
|
|
exit;
|
|
end;
|
|
chprFailed:
|
|
begin
|
|
{$IFDEF VerboseFPDocFails}
|
|
DebugLn(['TFPDocEditForm.UpdateChain failed CodeHelpBoss.GetElementChain for ',fSourceFilename,' ',dbgs(CaretXY)]);
|
|
{$ENDIF}
|
|
exit;
|
|
end;
|
|
else
|
|
{$IFDEF VerboseCodeHelp}
|
|
NewChain.WriteDebugReport;
|
|
{$ENDIF}
|
|
fChain:=NewChain;
|
|
fDocFile:=fChain.DocFile;
|
|
NewChain:=nil;
|
|
end;
|
|
finally
|
|
NewChain.Free;
|
|
end;
|
|
if (fDocFile=nil) then begin
|
|
// load default docfile, needed to show syntax errors in xml and for topics
|
|
fDocFile:=GetDefaultDocFile;
|
|
end;
|
|
OpenXMLButton.Enabled:=fDocFile<>nil;
|
|
if fDocFile<>nil then
|
|
OpenXMLButton.Hint:=fDocFile.Filename
|
|
else
|
|
OpenXMLButton.Hint:='';
|
|
end;
|
|
|
|
procedure TFPDocEditor.OnFPDocChanging(Sender: TObject;
|
|
FPDocFPFile: TLazFPDocFile);
|
|
begin
|
|
if fpdefWriting in FFlags then exit;
|
|
if (fChain<>nil) and (fChain.IndexOfFile(FPDocFPFile)>=0) then
|
|
InvalidateChain
|
|
else if (fDocFile<>nil) and (fDocFile=FPDocFPFile) then
|
|
Include(FFlags,fpdefTopicNeedsUpdate);
|
|
end;
|
|
|
|
procedure TFPDocEditor.OnFPDocChanged(Sender: TObject;
|
|
FPDocFPFile: TLazFPDocFile);
|
|
begin
|
|
if fpdefWriting in FFlags then exit;
|
|
if FPDocFPFile=nil then exit;
|
|
// maybe eventually update the editor
|
|
end;
|
|
|
|
procedure TFPDocEditor.LoadGUIValues(Element: TCodeHelpElement);
|
|
var
|
|
EnabledState: Boolean;
|
|
OldModified: Boolean;
|
|
begin
|
|
if fpdefReading in FFlags then exit;
|
|
OldModified:=FModified;
|
|
|
|
Include(FFlags,fpdefReading);
|
|
try
|
|
EnabledState := (Element<>nil) and (Element.ElementNode<>nil);
|
|
|
|
//CreateButton.Enabled := (Element<>nil) and (Element.ElementNode=nil)
|
|
// and (Element.ElementName<>'');
|
|
|
|
if EnabledState then
|
|
begin
|
|
FOldValues:=Element.FPDocFile.GetValuesFromNode(Element.ElementNode);
|
|
FOldVisualValues[fpdiShort]:=ReplaceLineEndings(FOldValues[fpdiShort],'');
|
|
FOldVisualValues[fpdiElementLink]:=LineBreaksToSystemLineBreaks(FOldValues[fpdiElementLink]);
|
|
FOldVisualValues[fpdiDescription]:=LineBreaksToSystemLineBreaks(FOldValues[fpdiDescription]);
|
|
FOldVisualValues[fpdiErrors]:=LineBreaksToSystemLineBreaks(FOldValues[fpdiErrors]);
|
|
FOldVisualValues[fpdiSeeAlso]:=LineBreaksToSystemLineBreaks(FOldValues[fpdiSeeAlso]);
|
|
FOldVisualValues[fpdiExample]:=LineBreaksToSystemLineBreaks(FOldValues[fpdiExample]);
|
|
//DebugLn(['TFPDocEditor.LoadGUIValues Short="',dbgstr(FOldValues[fpdiShort]),'"']);
|
|
end
|
|
else
|
|
begin
|
|
FOldVisualValues[fpdiShort]:='';
|
|
FOldVisualValues[fpdiElementLink]:='';
|
|
FOldVisualValues[fpdiDescription]:='';
|
|
FOldVisualValues[fpdiErrors]:='';
|
|
FOldVisualValues[fpdiSeeAlso]:='';
|
|
FOldVisualValues[fpdiExample]:='';
|
|
end;
|
|
ShortEdit.Text := FOldVisualValues[fpdiShort];
|
|
DescrShortEdit.Text := ShortEdit.Text;
|
|
//debugln(['TFPDocEditor.LoadGUIValues "',ShortEdit.Text,'" "',FOldVisualValues[fpdiShort],'"']);
|
|
LinkEdit.Text := FOldVisualValues[fpdiElementLink];
|
|
DescrSynEdit.Lines.Text := FOldVisualValues[fpdiDescription];
|
|
//debugln(['TFPDocEditor.LoadGUIValues DescrMemo="',dbgstr(DescrSynEdit.Lines.Text),'" Descr="',dbgstr(FOldVisualValues[fpdiDescription]),'"']);
|
|
SeeAlsoSynEdit.Text := FOldVisualValues[fpdiSeeAlso];
|
|
ErrorsSynEdit.Lines.Text := FOldVisualValues[fpdiErrors];
|
|
ExampleEdit.Text := FOldVisualValues[fpdiExample];
|
|
|
|
ShortEdit.Enabled := EnabledState;
|
|
DescrShortEdit.Enabled := ShortEdit.Enabled;
|
|
LinkEdit.Enabled := EnabledState;
|
|
DescrSynEdit.Enabled := EnabledState;
|
|
SeeAlsoSynEdit.Enabled := EnabledState;
|
|
ErrorsSynEdit.Enabled := EnabledState;
|
|
ExampleEdit.Enabled := EnabledState;
|
|
BrowseExampleButton.Enabled := EnabledState;
|
|
|
|
FModified:=OldModified;
|
|
SaveButton.Enabled:=false;
|
|
|
|
finally
|
|
Exclude(FFlags,fpdefReading);
|
|
end;
|
|
end;
|
|
|
|
procedure TFPDocEditor.MoveToInherited(Element: TCodeHelpElement);
|
|
var
|
|
Values: TFPDocElementValues;
|
|
begin
|
|
Values:=GetGUIValues;
|
|
WriteNode(Element,Values,true);
|
|
end;
|
|
|
|
function TFPDocEditor.ExtractIDFromLinkTag(const LinkTag: string; out ID, Title: string
|
|
): boolean;
|
|
// extract id and title from example:
|
|
// <link id="TCustomControl"/>
|
|
// <link id="#lcl.Graphics.TCanvas">TCanvas</link>
|
|
var
|
|
StartPos: Integer;
|
|
EndPos: LongInt;
|
|
begin
|
|
Result:=false;
|
|
ID:='';
|
|
Title:='';
|
|
StartPos:=length('<link id="')+1;
|
|
if copy(LinkTag,1,StartPos-1)<>'<link id="' then
|
|
exit;
|
|
EndPos:=StartPos;
|
|
while (EndPos<=length(LinkTag)) do begin
|
|
if LinkTag[EndPos]='"' then begin
|
|
ID:=copy(LinkTag,StartPos,EndPos-StartPos);
|
|
Title:='';
|
|
Result:=true;
|
|
// extract title
|
|
StartPos:=EndPos;
|
|
while (StartPos<=length(LinkTag)) and (LinkTag[StartPos]<>'>') do inc(StartPos);
|
|
if LinkTag[StartPos-1]='\' then begin
|
|
// no title
|
|
end else begin
|
|
// has title
|
|
inc(StartPos);
|
|
EndPos:=StartPos;
|
|
while (EndPos<=length(LinkTag)) and (LinkTag[EndPos]<>'<') do inc(EndPos);
|
|
Title:=copy(LinkTag,StartPos,EndPos-StartPos);
|
|
end;
|
|
exit;
|
|
end;
|
|
inc(EndPos);
|
|
end;
|
|
end;
|
|
|
|
function TFPDocEditor.CreateElement(Element: TCodeHelpElement): Boolean;
|
|
var
|
|
NewElement: TCodeHelpElement;
|
|
begin
|
|
//DebugLn(['TFPDocEditForm.CreateElement ']);
|
|
if (Element=nil) or (Element.ElementName='') then exit(false);
|
|
NewElement:=nil;
|
|
Include(FFlags,fpdefWriting);
|
|
try
|
|
Result:=CodeHelpBoss.CreateElement(Element.CodeXYPos.Code,
|
|
Element.CodeXYPos.X,Element.CodeXYPos.Y,NewElement);
|
|
finally
|
|
Exclude(FFlags,fpdefWriting);
|
|
NewElement.Free;
|
|
end;
|
|
Reset;
|
|
InvalidateChain;
|
|
end;
|
|
|
|
procedure TFPDocEditor.UpdateButtons;
|
|
var
|
|
HasEdit: Boolean;
|
|
begin
|
|
HasEdit:=(PageControl.ActivePage = ShortTabSheet)
|
|
or (PageControl.ActivePage = DescrTabSheet)
|
|
or (PageControl.ActivePage = SeeAlsoTabSheet)
|
|
or (PageControl.ActivePage = ErrorsTabSheet)
|
|
or (PageControl.ActivePage = TopicSheet);
|
|
BoldFormatButton.Enabled:=HasEdit;
|
|
ItalicFormatButton.Enabled:=HasEdit;
|
|
UnderlineFormatButton.Enabled:=HasEdit;
|
|
InsertCodeTagButton.Enabled:=HasEdit;
|
|
InsertLinkSpeedButton.Enabled:=HasEdit;
|
|
InsertParagraphSpeedButton.Enabled:=HasEdit;
|
|
InsertRemarkButton.Enabled:=HasEdit;
|
|
InsertVarTagButton.Enabled:=HasEdit;
|
|
InsertPrintShortSpeedButton.Enabled:=HasEdit;
|
|
InsertURLTagSpeedButton.Enabled:=HasEdit;
|
|
end;
|
|
|
|
function TFPDocEditor.GetCurrentUnitName: string;
|
|
begin
|
|
if (fChain<>nil) and (fChain.Count>0) then
|
|
Result:=fChain[0].ElementUnitName
|
|
else
|
|
Result:='';
|
|
end;
|
|
|
|
function TFPDocEditor.GetCurrentOwnerName: string;
|
|
begin
|
|
if (fChain<>nil) and (fChain.Count>0) then
|
|
Result:=fChain[0].ElementOwnerName
|
|
else
|
|
Result:='';
|
|
end;
|
|
|
|
procedure TFPDocEditor.JumpToError(Item: TFPDocItem; LineCol: TPoint);
|
|
begin
|
|
case Item of
|
|
fpdiShort: PageControl.ActivePage:=ShortTabSheet;
|
|
fpdiElementLink: PageControl.ActivePage:=InheritedTabSheet;
|
|
fpdiDescription:
|
|
begin
|
|
PageControl.ActivePage:=DescrTabSheet;
|
|
DescrSynEdit.CaretXY:=LineCol;
|
|
end;
|
|
fpdiErrors: PageControl.ActivePage:=ErrorsTabSheet;
|
|
fpdiSeeAlso: PageControl.ActivePage:=SeeAlsoTabSheet;
|
|
fpdiExample: PageControl.ActivePage:=ExampleTabSheet;
|
|
end;
|
|
end;
|
|
|
|
procedure TFPDocEditor.OpenXML;
|
|
var
|
|
CurDocFile: TLazFPDocFile;
|
|
begin
|
|
CurDocFile:=DocFile;
|
|
if CurDocFile=nil then exit;
|
|
if FileExistsUTF8(CurDocFile.Filename) then begin
|
|
LazarusIDE.DoOpenEditorFile(CurDocFile.Filename,-1,-1,
|
|
[ofOnlyIfExists,ofRegularFile,ofUseCache]);
|
|
end;
|
|
end;
|
|
|
|
function TFPDocEditor.GUIModified: boolean;
|
|
begin
|
|
if fpdefReading in FFlags then exit(false);
|
|
Result:=(ShortEdit.Text<>FOldVisualValues[fpdiShort])
|
|
or (LinkEdit.Text<>FOldVisualValues[fpdiElementLink])
|
|
or (DescrSynEdit.Text<>FOldVisualValues[fpdiDescription])
|
|
or (SeeAlsoSynEdit.Text<>FOldVisualValues[fpdiSeeAlso])
|
|
or (ErrorsSynEdit.Text<>FOldVisualValues[fpdiErrors])
|
|
or (ExampleEdit.Text<>FOldVisualValues[fpdiExample]);
|
|
if Result then begin
|
|
if (ShortEdit.Text<>FOldVisualValues[fpdiShort]) then
|
|
debugln(['TFPDocEditor.GUIModified Short ',dbgstr(ShortEdit.Text),' <> ',dbgstr(FOldVisualValues[fpdiShort])]);
|
|
if (LinkEdit.Text<>FOldVisualValues[fpdiElementLink]) then
|
|
debugln(['TFPDocEditor.GUIModified link ',dbgstr(LinkEdit.Text),' <> ',dbgstr(FOldVisualValues[fpdiElementLink])]);
|
|
if (DescrSynEdit.Text<>FOldVisualValues[fpdiDescription]) then
|
|
debugln(['TFPDocEditor.GUIModified Descr ',dbgstr(DescrSynEdit.Text),' <> ',dbgstr(FOldVisualValues[fpdiDescription])]);
|
|
if (SeeAlsoSynEdit.Text<>FOldVisualValues[fpdiSeeAlso]) then
|
|
debugln(['TFPDocEditor.GUIModified SeeAlso ',dbgstr(SeeAlsoSynEdit.Text),' <> ',dbgstr(FOldVisualValues[fpdiSeeAlso])]);
|
|
if (ErrorsSynEdit.Text<>FOldVisualValues[fpdiErrors]) then
|
|
debugln(['TFPDocEditor.GUIModified Errors ',dbgstr(ErrorsSynEdit.Text),' <> ',dbgstr(FOldVisualValues[fpdiErrors])]);
|
|
if (ExampleEdit.Text<>FOldVisualValues[fpdiExample]) then
|
|
debugln(['TFPDocEditor.GUIModified Example ',dbgstr(ExampleEdit.Text),' <> ',dbgstr(FOldVisualValues[fpdiExample])]);
|
|
end;
|
|
end;
|
|
|
|
procedure TFPDocEditor.DoEditorUpdate(Sender: TObject);
|
|
begin
|
|
if GetCaptureControl <> nil then // If SynEdit has Capture the user may be selecting by Mouse. https://bugs.freepascal.org/view.php?id=37150
|
|
exit;
|
|
if FollowCursor then
|
|
LoadIdentifierAtCursor;
|
|
end;
|
|
|
|
procedure TFPDocEditor.DoEditorMouseUp(Sender: TObject);
|
|
begin
|
|
if FollowCursor then
|
|
LoadIdentifierAtCursor;
|
|
end;
|
|
|
|
procedure TFPDocEditor.UpdateTopicCombo;
|
|
var
|
|
cnt, i: LongInt;
|
|
DFile: TLazFPDocFile;
|
|
Topics: TStringList;
|
|
begin
|
|
Exclude(FFlags,fpdefTopicNeedsUpdate);
|
|
Topics:=TStringList.Create;
|
|
Include(FFlags,fpdefTopicSettingUp);
|
|
try
|
|
Dfile := DocFile;
|
|
if DFile<>nil then begin
|
|
cnt := DFile.GetModuleTopicCount;
|
|
for i := 0 to cnt - 1 do
|
|
Topics.Add(DFile.GetModuleTopicName(i));
|
|
end;
|
|
TopicListBox.Items.Assign(Topics);
|
|
TopicListBox.ItemIndex:=TopicListBox.Items.IndexOf(FCurrentTopic);
|
|
UpdateTopic;
|
|
finally
|
|
Exclude(FFlags,fpdefTopicSettingUp);
|
|
Topics.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TFPDocEditor.SetIdleConnected(AValue: boolean);
|
|
begin
|
|
if FIdleConnected=AValue then Exit;
|
|
FIdleConnected:=AValue;
|
|
if IdleConnected then
|
|
Application.AddOnIdleHandler(@ApplicationIdle)
|
|
else
|
|
Application.RemoveOnIdleHandler(@ApplicationIdle);
|
|
end;
|
|
|
|
procedure TFPDocEditor.SetFollowCursor(AValue: boolean);
|
|
begin
|
|
if FFollowCursor=AValue then Exit;
|
|
FFollowCursor:=AValue;
|
|
if FollowCursor then
|
|
LoadIdentifierAtCursor;
|
|
end;
|
|
|
|
function TFPDocEditor.GetDefaultDocFile(CreateIfNotExists: Boolean): TLazFPDocFile;
|
|
var
|
|
CacheWasUsed : Boolean;
|
|
AnOwner: TObject;
|
|
FPDocFileName: String;
|
|
begin
|
|
Result := nil;
|
|
if (not CreateIfNotExists) and (fDocFile<>nil) then
|
|
exit(fDocFile);
|
|
|
|
FPDocFileName := CodeHelpBoss.GetFPDocFilenameForSource(SourceFilename, true,
|
|
CacheWasUsed, AnOwner, CreateIfNotExists);
|
|
if (FPDocFileName = '')
|
|
or (CodeHelpBoss.LoadFPDocFile(FPDocFileName, [chofUpdateFromDisk], Result,
|
|
CacheWasUsed) <> chprSuccess)
|
|
then
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TFPDocEditor.Reset;
|
|
var
|
|
i: TFPDocItem;
|
|
begin
|
|
FreeAndNil(fChain);
|
|
if fpdefReading in FFlags then exit;
|
|
Include(FFlags,fpdefReading);
|
|
try
|
|
// clear all element editors/viewers
|
|
ShortEdit.Clear;
|
|
DescrShortEdit.Clear;
|
|
LinkEdit.Clear;
|
|
DescrSynEdit.Clear;
|
|
SeeAlsoSynEdit.Clear;
|
|
ErrorsSynEdit.Clear;
|
|
ExampleEdit.Clear;
|
|
ClearTopicControls;
|
|
for i:=Low(TFPDocItem) to high(TFPDocItem) do
|
|
FOldVisualValues[i]:='';
|
|
|
|
Modified := False;
|
|
//CreateButton.Enabled:=false;
|
|
OpenXMLButton.Enabled:=false;
|
|
finally
|
|
Exclude(FFlags,fpdefReading);
|
|
end;
|
|
end;
|
|
|
|
procedure TFPDocEditor.InvalidateChain;
|
|
begin
|
|
FreeAndNil(fChain);
|
|
FFlags:=FFlags+[fpdefCodeCacheNeedsUpdate,
|
|
fpdefChainNeedsUpdate,fpdefCaptionNeedsUpdate,
|
|
fpdefValueControlsNeedsUpdate,fpdefInheritedControlsNeedsUpdate];
|
|
IdleConnected:=true;
|
|
end;
|
|
|
|
procedure TFPDocEditor.LoadIdentifierAt(const SrcFilename: string;
|
|
const Caret: TPoint);
|
|
var
|
|
NewSrcFilename: String;
|
|
begin
|
|
//debugln(['TFPDocEditor.LoadIdentifierAt START ',SrcFilename,' ',dbgs(Caret)]);
|
|
// save the current changes to documentation
|
|
Save(IsVisible);
|
|
|
|
NewSrcFilename:=TrimAndExpandFilename(SrcFilename);
|
|
if (NewSrcFilename=SourceFilename) and (CompareCaret(Caret,CaretXY)=0)
|
|
and (fChain<>nil) and fChain.IsValid
|
|
and (not LazarusIDE.NeedSaveSourceEditorChangesToCodeCache(nil)) then
|
|
exit;
|
|
|
|
FCaretXY:=Caret;
|
|
fSourceFilename:=NewSrcFilename;
|
|
|
|
Reset;
|
|
Include(FFlags,fpdefTopicNeedsUpdate);
|
|
InvalidateChain;
|
|
end;
|
|
|
|
procedure TFPDocEditor.LoadIdentifierAtCursor;
|
|
var
|
|
SrcEdit: TSourceEditorInterface;
|
|
begin
|
|
if SourceEditorManagerIntf=nil then exit;
|
|
if csDestroying in ComponentState then exit;
|
|
if FFlags*[fpdefReading,fpdefWriting]<>[] then exit;
|
|
SrcEdit:=SourceEditorManagerIntf.ActiveEditor;
|
|
if SrcEdit=nil then
|
|
Reset
|
|
else
|
|
LoadIdentifierAt(SrcEdit.FileName,SrcEdit.CursorTextXY);
|
|
end;
|
|
|
|
procedure TFPDocEditor.BeginUpdate;
|
|
begin
|
|
inc(fUpdateLock);
|
|
end;
|
|
|
|
procedure TFPDocEditor.EndUpdate;
|
|
begin
|
|
dec(fUpdateLock);
|
|
if fUpdateLock<0 then LazTracer.RaiseGDBException('');
|
|
if fUpdateLock=0 then begin
|
|
if fpdefCaptionNeedsUpdate in FFlags then UpdateCaption;
|
|
end;
|
|
end;
|
|
|
|
procedure TFPDocEditor.ClearEntry(DoSave: Boolean);
|
|
begin
|
|
Modified:=true;
|
|
ShortEdit.Text:='';
|
|
DescrShortEdit.Text:=ShortEdit.Text;
|
|
DescrSynEdit.Text:='';
|
|
SeeAlsoSynEdit.Text:='';
|
|
ErrorsSynEdit.Text:='';
|
|
ExampleEdit.Text:='';
|
|
if DoSave then Save;
|
|
end;
|
|
|
|
procedure TFPDocEditor.Save(CheckGUI: boolean);
|
|
var
|
|
Values: TFPDocElementValues;
|
|
TopicDocFile: TLazFPDocFile;
|
|
Node: TDOMNode;
|
|
Child: TDOMNode;
|
|
TopicChanged: Boolean;
|
|
begin
|
|
//DebugLn(['TFPDocEditor.Save FModified=',FModified]);
|
|
if fpdefReading in FFlags then exit;
|
|
|
|
if (not FModified)
|
|
and ((not CheckGUI) or (not GUIModified)) then
|
|
begin
|
|
SaveButton.Enabled:=false;
|
|
Exit; // nothing changed => exit
|
|
end;
|
|
//DebugLn(['TFPDocEditor.Save FModified=',FModified,' CheckGUI=',CheckGUI,' GUIModified=',GUIModified]);
|
|
FModified:=false;
|
|
SaveButton.Enabled:=false;
|
|
|
|
TopicChanged:=false;
|
|
TopicDocFile:=DocFile;
|
|
if FCurrentTopic <> '' then
|
|
begin
|
|
if fDocFile=nil then
|
|
fDocFile := GetDefaultDocFile(True);
|
|
TopicDocFile:=DocFile;
|
|
if TopicDocFile <> nil then begin
|
|
Node := TopicDocFile.GetModuleTopic(FCurrentTopic);
|
|
if Node <> nil then begin
|
|
Child := Node.FindNode('short');
|
|
if (Child = nil)
|
|
or (TopicDocFile.GetChildValuesAsString(Child)<>TopicShort.Text)
|
|
then begin
|
|
TopicDocFile.SetChildValue(Node, 'short', TopicShort.Text);
|
|
TopicChanged:=true;
|
|
end;
|
|
Child := Node.FindNode('descr');
|
|
if (Child = nil)
|
|
or (TopicDocFile.GetChildValuesAsString(Child)<>TopicDescrSynEdit.Text)
|
|
then begin
|
|
TopicDocFile.SetChildValue(Node, 'descr', TopicDescrSynEdit.Text);
|
|
TopicChanged:=true;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
if (fChain=nil) or (fChain.Count=0) then
|
|
begin
|
|
if IsVisible then
|
|
DebugLn(['TFPDocEditor.Save failed: no chain']);
|
|
end else if not fChain.IsValid then
|
|
begin
|
|
if IsVisible then
|
|
DebugLn(['TFPDocEditor.Save failed: chain not valid']);
|
|
end else if (fChain[0].FPDocFile <> nil) then
|
|
begin
|
|
Values:=GetGUIValues;
|
|
if WriteNode(fChain[0],Values,true) then
|
|
begin
|
|
// write succeeded
|
|
if fChain.DocFile=TopicDocFile then
|
|
TopicChanged:=false;
|
|
end else begin
|
|
DebugLn(['TFPDocEditor.Save WriteNode FAILED']);
|
|
end;
|
|
end;
|
|
if TopicChanged then begin
|
|
Include(FFlags,fpdefWriting);
|
|
try
|
|
CodeHelpBoss.SaveFPDocFile(TopicDocFile);
|
|
finally
|
|
Exclude(FFlags,fpdefWriting);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TFPDocEditor.GetGUIValues: TFPDocElementValues;
|
|
var
|
|
i: TFPDocItem;
|
|
begin
|
|
Result[fpdiShort]:=ShortEdit.Text;
|
|
Result[fpdiDescription]:=DescrSynEdit.Text;
|
|
Result[fpdiErrors]:=ErrorsSynEdit.Text;
|
|
Result[fpdiSeeAlso]:=SeeAlsoSynEdit.Text;
|
|
Result[fpdiExample]:=ExampleEdit.Text;
|
|
Result[fpdiElementLink]:=LinkEdit.Text;
|
|
for i:=Low(TFPDocItem) to High(TFPDocItem) do
|
|
if Trim(Result[i])='' then
|
|
Result[i]:='';
|
|
end;
|
|
|
|
procedure TFPDocEditor.SetModified(const AValue: boolean);
|
|
begin
|
|
if FModified=AValue then exit;
|
|
FModified:=AValue;
|
|
SaveButton.Enabled:=FModified;
|
|
//debugln(['TFPDocEditor.SetModified New=',FModified]);
|
|
end;
|
|
|
|
procedure TFPDocEditor.UpdateTopic;
|
|
var
|
|
Child: TDOMNode;
|
|
Node: TDOMNode;
|
|
DFile: TLazFPDocFile;
|
|
begin
|
|
FCurrentTopic := '';
|
|
try
|
|
if TopicListBox.ItemIndex < 0 then exit;
|
|
Dfile := GetDefaultDocFile(True);
|
|
if DFile = nil then exit;
|
|
|
|
FCurrentTopic := TopicListBox.Items[TopicListBox.ItemIndex];
|
|
Node := DFile.GetModuleTopic(FCurrentTopic);
|
|
if Node = nil then exit;
|
|
|
|
Include(FFlags, fpdefTopicSettingUp);
|
|
try
|
|
Child := Node.FindNode('short');
|
|
if Child <> nil then
|
|
TopicShort.Text := DFile.GetChildValuesAsString(Child);
|
|
Child := Node.FindNode('descr');
|
|
if Child <> nil then
|
|
TopicDescrSynEdit.Text := DFile.GetChildValuesAsString(Child);
|
|
TopicShort.Enabled := True;
|
|
TopicDescrSynEdit.Enabled := True;
|
|
if TopicShort.IsVisible then
|
|
TopicShort.SetFocus;
|
|
finally
|
|
Exclude(FFlags, fpdefTopicSettingUp);
|
|
end;
|
|
finally
|
|
if FCurrentTopic='' then
|
|
ClearTopicControls;
|
|
end;
|
|
end;
|
|
|
|
procedure TFPDocEditor.UpdateShowing;
|
|
begin
|
|
inherited UpdateShowing;
|
|
if IsVisible and (fpdefWasHidden in FFlags) then begin
|
|
Exclude(FFlags,fpdefWasHidden);
|
|
LoadIdentifierAtCursor;
|
|
end;
|
|
end;
|
|
|
|
procedure TFPDocEditor.Loaded;
|
|
begin
|
|
inherited Loaded;
|
|
DescrSynEdit.ControlStyle:=DescrSynEdit.ControlStyle+[];
|
|
end;
|
|
|
|
function TFPDocEditor.WriteNode(Element: TCodeHelpElement;
|
|
Values: TFPDocElementValues; Interactive: Boolean): Boolean;
|
|
var
|
|
TopNode: TDOMNode;
|
|
CurDocFile: TLazFPDocFile;
|
|
CurDoc: TXMLDocument;
|
|
|
|
function Check(Test: boolean; const Msg: string): Boolean;
|
|
var
|
|
CurName: String;
|
|
begin
|
|
Result:=Test;
|
|
if not Test then exit;
|
|
DebugLn(['TFPDocEditor.WriteNode ERROR ',Msg]);
|
|
if Interactive then begin;
|
|
if Element.FPDocFile<>nil then
|
|
CurName:=Element.FPDocFile.Filename
|
|
else
|
|
CurName:=Element.ElementName;
|
|
IDEMessageDialog(lisCodeToolsDefsWriteError,
|
|
Format(lisFPDocErrorWriting, [CurName, LineEnding, Msg]), mtError, [mbCancel]);
|
|
end;
|
|
end;
|
|
|
|
function SetValue(Item: TFPDocItem): boolean;
|
|
var
|
|
NewValue: String;
|
|
begin
|
|
Result:=false;
|
|
NewValue:=Values[Item];
|
|
try
|
|
FixFPDocFragment(NewValue,
|
|
Item in [fpdiShort,fpdiDescription,fpdiErrors,fpdiSeeAlso],
|
|
true);
|
|
CurDocFile.SetChildValue(TopNode,FPDocItemNames[Item],NewValue);
|
|
Result:=true;
|
|
except
|
|
on E: EXMLReadError do begin
|
|
DebugLn(['SetValue ',dbgs(E.LineCol),' Name=',FPDocItemNames[Item]]);
|
|
JumpToError(Item,E.LineCol);
|
|
IDEMessageDialog(lisFPDocFPDocSyntaxError,
|
|
Format(lisFPDocThereIsASyntaxErrorInTheFpdocElement, [FPDocItemNames
|
|
[Item], LineEnding+LineEnding, E.Message]), mtError, [mbOk], '');
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
Result:=false;
|
|
if fpdefWriting in FFlags then begin
|
|
DebugLn(['TFPDocEditForm.WriteNode inconsistency detected: recursive write']);
|
|
exit;
|
|
end;
|
|
|
|
if Check(Element=nil,'Element=nil') then exit;
|
|
CurDocFile:=Element.FPDocFile;
|
|
if Check(CurDocFile=nil,'Element.FPDocFile=nil') then begin
|
|
// no fpdoc file found
|
|
DebugLn(['TFPDocEditForm.WriteNode TODO: implement creating new fpdoc file']);
|
|
exit;
|
|
end;
|
|
CurDoc:=CurDocFile.Doc;
|
|
if Check(CurDoc=nil,'Element.FPDocFile.Doc=nil') then exit;
|
|
if Check(not Element.ElementNodeValid,'not Element.ElementNodeValid') then exit;
|
|
TopNode:=Element.ElementNode;
|
|
if Check(TopNode=nil,'TopNode=nil') then begin
|
|
// no old node found
|
|
Check(false,'no old node found. TODO: implement creating a new.');
|
|
Exit;
|
|
end;
|
|
|
|
Include(FFlags,fpdefWriting);
|
|
CurDocFile.BeginUpdate;
|
|
try
|
|
if SetValue(fpdiShort)
|
|
and SetValue(fpdiElementLink)
|
|
and SetValue(fpdiDescription)
|
|
and SetValue(fpdiErrors)
|
|
and SetValue(fpdiSeeAlso)
|
|
and SetValue(fpdiExample) then
|
|
;
|
|
finally
|
|
CurDocFile.EndUpdate;
|
|
fChain.MakeValid;
|
|
Exclude(FFlags,fpdefWriting);
|
|
end;
|
|
|
|
if CodeHelpBoss.SaveFPDocFile(CurDocFile)<>mrOk then begin
|
|
DebugLn(['TFPDocEditForm.WriteNode failed writing ',CurDocFile.Filename]);
|
|
exit;
|
|
end;
|
|
Result:=true;
|
|
end;
|
|
|
|
procedure TFPDocEditor.UpdateCodeCache;
|
|
begin
|
|
if fUpdateLock>0 then begin
|
|
Include(FFlags,fpdefCodeCacheNeedsUpdate);
|
|
exit;
|
|
end;
|
|
Exclude(FFlags,fpdefCodeCacheNeedsUpdate);
|
|
LazarusIDE.SaveSourceEditorChangesToCodeCache(nil);
|
|
end;
|
|
|
|
procedure TFPDocEditor.ErrorsSynEditChange(Sender: TObject);
|
|
begin
|
|
if fpdefReading in FFlags then exit;
|
|
if ErrorsSynEdit.Text<>FOldVisualValues[fpdiErrors] then
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TFPDocEditor.ExampleEditChange(Sender: TObject);
|
|
begin
|
|
if fpdefReading in FFlags then exit;
|
|
if ExampleEdit.Text<>FOldVisualValues[fpdiExample] then
|
|
Modified:=true;
|
|
end;
|
|
|
|
function TFPDocEditor.FindInheritedIndex: integer;
|
|
// returns Index in chain of an overriden Element with a short description
|
|
// returns -1 if not found
|
|
var
|
|
Element: TCodeHelpElement;
|
|
begin
|
|
if (fChain<>nil) then begin
|
|
Result:=1;
|
|
while (Result<fChain.Count) do begin
|
|
Element:=fChain[Result];
|
|
if (Element.ElementNode<>nil)
|
|
and (Element.FPDocFile.GetValueFromNode(Element.ElementNode,fpdiShort)<>'')
|
|
then
|
|
exit;
|
|
inc(Result);
|
|
end;
|
|
end;
|
|
Result:=-1;
|
|
end;
|
|
|
|
procedure TFPDocEditor.AddLinkToInheritedButtonClick(Sender: TObject);
|
|
var
|
|
i: LongInt;
|
|
Element: TCodeHelpElement;
|
|
Link: String;
|
|
begin
|
|
i:=FindInheritedIndex;
|
|
if i<0 then exit;
|
|
//DebugLn(['TFPDocEditor.AddLinkToInheritedButtonClick ']);
|
|
Element:=fChain[i];
|
|
Link:=Element.ElementName;
|
|
if Element.ElementUnitName<>'' then begin
|
|
Link:=Element.ElementUnitName+'.'+Link;
|
|
if Element.ElementFPDocPackageName<>'' then
|
|
Link:='#'+Element.ElementFPDocPackageName+'.'+Link;
|
|
end;
|
|
if Link<>LinkEdit.Text then begin
|
|
LinkEdit.Text:=Link;
|
|
Modified:=true;
|
|
end;
|
|
end;
|
|
|
|
procedure TFPDocEditor.BrowseExampleButtonClick(Sender: TObject);
|
|
begin
|
|
if Doc=nil then exit;
|
|
InitIDEFileDialog(OpenDialog);
|
|
OpenDialog.Title:=lisChooseAnExampleFile;
|
|
OpenDialog.Filter:=dlgFilterPascalFile+'|*.pas;*.pp;*.p|'+dlgFilterAll+'|'+FileMask;
|
|
OpenDialog.InitialDir:=ExtractFilePath(DocFile.Filename);
|
|
if OpenDialog.Execute then begin
|
|
ExampleEdit.Text := ExtractRelativepath(
|
|
ExtractFilePath(DocFile.Filename), GetForcedPathDelims(OpenDialog.FileName));
|
|
if ExampleEdit.Text<>FOldVisualValues[fpdiExample] then
|
|
Modified:=true;
|
|
end;
|
|
StoreIDEFileDialog(OpenDialog);
|
|
end;
|
|
|
|
procedure TFPDocEditor.CopyFromInheritedButtonClick(Sender: TObject);
|
|
var
|
|
i: LongInt;
|
|
begin
|
|
i:=FindInheritedIndex;
|
|
if i<0 then exit;
|
|
//DebugLn(['TFPDocEditForm.CopyFromInheritedButtonClick ']);
|
|
if ShortEdit.Text<>'' then begin
|
|
if IDEQuestionDialog(lisConfirmReplace,
|
|
GetContextTitle(fChain[0])+' already contains the help:'+LineEnding+ShortEdit.Text,
|
|
mtConfirmation, [mrYes, lisReplace,
|
|
mrCancel]) <> mrYes then exit;
|
|
end;
|
|
LoadGUIValues(fChain[i]);
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TFPDocEditor.CopyShortToDescrMenuItemClick(Sender: TObject);
|
|
begin
|
|
DescrSynEdit.Append(ShortEdit.Text);
|
|
Modified:=true;
|
|
end;
|
|
|
|
procedure TFPDocEditor.CreateButtonClick(Sender: TObject);
|
|
begin
|
|
if ((fChain=nil) or (fChain.Count=0))
|
|
or (TCodeHelpElement(fChain[0]).ElementName='') then begin
|
|
IDEMessageDialog(lisInvalidDeclaration, lisPleasePlaceTheEditorCaretOnAnIdentifierIfThisIsANe,
|
|
mtError,[mbOK]);
|
|
exit;
|
|
end;
|
|
CreateElement(fChain[0]);
|
|
end;
|
|
|
|
procedure TFPDocEditor.DescrSynEditChange(Sender: TObject);
|
|
begin
|
|
if fpdefReading in FFlags then exit;
|
|
if DescrSynEdit.Text<>FOldVisualValues[fpdiDescription] then
|
|
Modified:=true;
|
|
end;
|
|
|
|
end.
|