Recent

Author Topic: Help - Developing an IDE Extension - Access Package from Menu  (Read 187 times)

gcscaglia

  • Newbie
  • Posts: 4
I'm trying to develop an IDE Extension for Lazarus (following https://wiki.lazarus.freepascal.org/Extending_the_IDE).

While there are examples of how to get the currently open project, all examples I've found for opening packages assume the developer knows the package name.

I'm trying to develop an extension that will be accessed via a menu item on the Package Editor form. I've succeeded in creating the menu item, as follows:

Code: Pascal  [Select][+][-]
  1. unit UGenerateGitIgnore;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, MenuIntf;
  9.  
  10. procedure WriteGitIgnoreForPackage(Sender: TObject);
  11.  
  12. procedure Register;
  13.  
  14. implementation
  15.  
  16. procedure WriteGitIgnoreForPackage(Sender: TObject);
  17. begin
  18. end;
  19.  
  20. procedure Register;
  21. begin
  22.   RegisterIDEMenuCommand(
  23.       PkgEditMenuSectionMisc,
  24.       'gitignore',
  25.       'Generate .gitignore',
  26.       nil,
  27.       @WriteGitIgnoreForPackage
  28.   );
  29. end;
  30.  
  31. end.
  32.  

My current problem is, how do I know, inside the WriteGitIgnoreForPackage procedure, which package did the user clicked the menu item from?

For this particular use case what I really must know is where the .lpk file resides, but ideally I would be able to get an TIDEPackage reference.

I've already tried using
Code: Pascal  [Select][+][-]
  1. PackageEditingInterface.GetPackageOfEditorItem(Sender);
(found this being done on ToDoDlg.pas, on lazarus/components/todolist) but this always returns nil.

gcscaglia

  • Newbie
  • Posts: 4
Re: Help - Developing an IDE Extension - Access Package from Menu
« Reply #1 on: June 15, 2022, 06:28:50 pm »
To future readers:

Shame on me, reading lazarus/packager/pkgmanager.pas solved my problem:

Code: Pascal  [Select][+][-]
  1. function TPkgManager.GetPackageOfEditorItem(Sender: TObject): TIDEPackage;
  2. begin
  3.   Result:=nil;
  4.   while (Sender is TMenuItem) and (TMenuItem(Sender).Parent<>nil) do
  5.     Sender:=TMenuItem(Sender).Parent;
  6.   if (Sender is TMenuItem) and (TMenuItem(Sender).Menu<>nil)
  7.   then
  8.     Sender:=TMenuItem(Sender).Menu;
  9.   if (Sender is TComponent) and (TComponent(Sender).Owner is TCustomForm) then
  10.     Sender:=TCustomForm(TComponent(Sender).Owner);
  11.   if Sender is TPackageEditorForm then
  12.     Result:=TPackageEditorForm(Sender).LazPackage;
  13. end;
  14.  

In other words: I need to pass a TComponent into PackageEditingInterface.GetPackageOfEditorItem. On my particular case, Sender was an TIDEMenuCommand instance. Modifying WriteGitIgnoreForPackage as follows worked for me:

Code: Pascal  [Select][+][-]
  1. procedure WriteGitIgnoreForPackage(Sender: TObject);
  2. var
  3.   lCmd: TComponent;
  4.   lPkg: TIDEPackage;
  5. begin
  6.   if (Sender is TIDEMenuCommand) then
  7.     lCmd := TIDEMenuCommand(Sender).MenuItem
  8.   else if (Sender is TComponent) then
  9.     lCmd := TComponent(Sender)
  10.   else
  11.     ShowMessage('Unsupported Sender!');
  12.  
  13.   lPkg := PackageEditingInterface.GetPackageOfEditorItem(lCmd);
  14.   ShowMessage('Pkg: ' + lPkg.Name);
  15. end;
  16.  

I'm probably going to submit a patch for GetPackageOfEditorItem to check for TIDEMenuCommand as well.

 

TinyPortal © 2005-2018