SynEdit: add TSynPopupMenu with default items for editor. Issue #38792 Patch by Joeny Ang "biloky"

This commit is contained in:
Martin 2023-06-21 00:46:34 +02:00
parent 5821b61cdc
commit 81f407e030
9 changed files with 155 additions and 3 deletions

View File

@ -32,10 +32,9 @@ uses
SynHighlighterIni, SynEditMarkupSpecialChar, SynEditTextDoubleWidthChars,
SynEditTextSystemCharWidth, SynEditMarkupIfDef, SynPluginMultiCaret,
synhighlighterpike, SynEditMarkupFoldColoring, SynEditViewedLineMap,
SynEditWrappedView, SynBeautifierPascal, LazSynIMMBase, LazarusPackageIntf;
SynEditWrappedView, SynBeautifierPascal, LazSynIMMBase, SynPopupMenu, LazarusPackageIntf;
implementation
procedure Register;
begin
RegisterUnit('SynEdit', @SynEdit.Register);

View File

@ -43,7 +43,7 @@ uses
SynHighlighterCss, SynHighlighterPHP, SynHighlighterTeX, SynHighlighterSQL,
SynHighlighterPython, SynHighlighterVB, SynHighlighterAny, SynHighlighterDiff,
SynHighlighterBat, SynHighlighterIni, SynHighlighterPo,
SynPluginSyncroEdit,
SynPluginSyncroEdit, SynPopupMenu,
SynPropertyEditObjectList, SynDesignStringConstants, SynHighlighterJScript,
LazarusPackageIntf, LResources, PropEdits, ComponentEditors;
@ -88,6 +88,11 @@ begin
{$EndIF}
end;
procedure RegisterSynPopupMenu;
begin
RegisterComponents('SynEdit',[TSynPopupMenu]);
end;
procedure RegisterSynHighlighterPas;
begin
RegisterComponents('SynEdit',[TSynPasSyn, TSynFreePascalSyn]);
@ -233,6 +238,7 @@ begin
RegisterSynMacroRecorder;
RegisterSynExportHTML;
RegisterSynSyncroEdit;
RegisterSynPopupMenu;
RegisterSynHighlighterPas;;
RegisterSynHighlighterCPP;

View File

@ -85,3 +85,6 @@ tsynvbsyn_200.png
tsynxmlsyn.png
tsynxmlsyn_150.png
tsynxmlsyn_200.png
tsynpopupmenu.png
tsynpopupmenu_150.png
tsynpopupmenu_200.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -403,6 +403,10 @@ If you wish to allow use of your version of these files only under the terms of
<Filename Value="lazsynimmbase.pas"/>
<UnitName Value="LazSynIMMBase"/>
</Item>
<Item>
<Filename Value="synpopupmenu.pas"/>
<UnitName Value="SynPopupMenu"/>
</Item>
</Files>
<LazDoc Paths="docs\xml"/>
<i18n>

View File

@ -0,0 +1,140 @@
unit SynPopupMenu;
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, Menus, SynEdit;
type
TSynDefaultPopupMenu = (dpmDisabled, dpmBefore, dpmAfter);
TSynPopupMenu = class(TPopupMenu)
private
FDefaultPopupMenu: TSynDefaultPopupMenu;
procedure FillDefaultMenu;
procedure ClearDefaultMenu;
protected
procedure ItemOnClick(Sender: TObject);
public
constructor Create(AOwner: TComponent); override;
procedure PopUp(X, Y: Integer); override;
published
property DefaultPopupMenu: TSynDefaultPopupMenu read
FDefaultPopupMenu write FDefaultPopupMenu default dpmBefore;
end;
implementation
type
TMenuEntry = (meNone, meUndo, meRedo, meCut, meCopy, mePaste,
meDelete, meSelectAll);
resourcestring
SYNS_Undo = '&Undo';
SYNS_Redo = '&Redo';
SYNS_Cut = 'C&ut';
SYNS_Copy = '&Copy';
SYNS_Paste = '&Paste';
SYNS_Delete = '&Delete';
SYNS_SelectAll = 'Select &all';
{ TSynPopupMenu }
constructor TSynPopupMenu.Create(AOwner: TComponent);
begin
inherited;
FDefaultPopupMenu := dpmBefore;
end;
procedure TSynPopupMenu.FillDefaultMenu;
var
i: Integer;
procedure AddMenuItem(const ACaption: string; const ATag: TMenuEntry);
var
FItem: TMenuItem;
begin
FItem := TMenuItem.Create(Self);
FItem.Caption := ACaption;
FItem.OnClick := @ItemOnClick;
FItem.Tag := Integer(ATag);
if FDefaultPopupMenu = dpmAfter then
Items.Add(FItem)
else
Items.Insert(i, FItem);
Inc(i);
end;
var
FEmpty: Boolean;
begin
if FDefaultPopupMenu = dpmDisabled then
Exit;
i := 0;
FEmpty := Items.Count = 0;
if not FEmpty and (FDefaultPopupMenu = dpmAfter) then // separator
AddMenuItem('-', meNone);
AddMenuItem(SYNS_Undo, meUndo);
AddMenuItem(SYNS_Redo, meRedo);
AddMenuItem('-', meNone);
AddMenuItem(SYNS_Cut, meCut);
AddMenuItem(SYNS_Copy, meCopy);
AddMenuItem(SYNS_Paste, mePaste);
AddMenuItem('-', meNone);
AddMenuItem(SYNS_Delete, meDelete);
AddMenuItem(SYNS_SelectAll, meSelectAll);
if not FEmpty and (FDefaultPopupMenu = dpmBefore) then // separator
AddMenuItem('-', meNone);
end;
procedure TSynPopupMenu.ClearDefaultMenu;
var
i: Integer;
begin
for i := Items.Count - 1 downto 0 do
if Items[i].OnClick = @ItemOnClick then
Items.Delete(i);
end;
procedure TSynPopupMenu.ItemOnClick(Sender: TObject);
begin
with TCustomSynEdit(PopupComponent) do
case TMenuEntry(TMenuItem(Sender).Tag) of
meUndo: Undo;
meRedo: Redo;
meCut: CutToClipboard;
meCopy: CopyToClipboard;
mePaste: PasteFromClipboard;
meDelete: SelText := '';
meSelectAll: SelectAll;
end;
end;
procedure TSynPopupMenu.PopUp(X, Y: Integer);
var
i: Integer;
begin
ClearDefaultMenu;
if PopupComponent is TCustomSynEdit then
begin
FillDefaultMenu;
for i := 0 to Items.Count - 1 do
with TCustomSynEdit(PopupComponent) do
if Items[i].OnClick = @ItemOnClick then // make sure it's ours
case TMenuEntry(Items[i].Tag) of
meUndo: Items[i].Enabled := CanUndo;
meRedo: Items[i].Enabled := CanRedo;
meCut: Items[i].Enabled := SelAvail and not ReadOnly;
meCopy: Items[i].Enabled := SelAvail;
mePaste: Items[i].Enabled := CanPaste;
meDelete: Items[i].Enabled := SelAvail and not ReadOnly;
meSelectAll: Items[i].Enabled := Trim(Lines.Text) <> '';
end;
end;
inherited;
end;
end.