Extending the IDE

From Lazarus-ccr

Jump to: navigation, search

Deutsch (de) English (en) Français (fr) Japanese (ja) Slovensky (sk)

Contents

[edit] Extending the IDE

[edit] Overview

The IDE supports several types of plugins:

Components 
These are the items in the component palette. For a example TButton can be used to create Buttons.
Component Editors 
Component editors are used when you double click on a component in the designer or to add some extra items to the popup menu of the designer, when you right click on a component.
Property Editors 
These are used by the rows in the object inspector.
Experts 
These are all other types.


There are two possibilities to add your own plugins to Lazarus:

  1. Write a package, install it and register your plugins in the 'Register' procedure of a unit.
  2. Extend the lazarus code, and send your svn diff to the lazarus mailing list.

[edit] Writing components

You can create new components via the package editor. For example: Create or open a package, click on add, click on New Component, fill in the items: Ancestor Type = TButton, New class name = TMyButton, palette page = Misc, Unit file name = mybutton.pas (this file will be created), unit name MyButton and click ok.

[edit] Giving a new component an icon for the component palette

For example give TMyButton an icon. Create an image file of the format .bmp, .xpm or .png with the same name as the component class. For example tmybutton.png and save it in the package source directory. The image can be created by any graphic program (e.g. gimp) and should be no bigger than 24x24 pixel. Then convert the image to a .lrs file with the lazres tool, which can be found in the lazarus/tools directory:

 ~/lazarus/tools/lazres mybutton.lrs mybutton.png

This creates an pascal include file, which is used in the initialization section of mybutton.pas:

 initialization
   {$I mybutton.lrs}

Install the package.

[edit] Writing component editors

ToDo Hint: see componenteditors.pas for examples

[edit] Writing property editors

ToDo Hint: see propedits.pp for examples

[edit] Register event handlers

There are several events in the IDE, for which plugins can add their own handlers.

[edit] Designer events

In propedits.pp there is a "GlobalDesignHook" object, which maintains several events for designing. Each event calls a list of handlers. The default handlers are added by the IDE. You can add your own handlers with the AddHandlerXXX and RemoveHandlerXXX methods. They will be called before the default handlers.

Examples:

 Adding your handler (this is normally done in the constructor of your object):
   GlobalDesignHook.AddHandlerComponentAdded(@YourOnComponentAdded);
Removing your handler: GlobalDesignHook.RemoveHandlerComponentAdded(@YourOnComponentAdded);
You can remove all handlers at once. For example, it is a good idea to add this line in the destructor of object: GlobalDesignHook.RemoveAllHandlersForObject(Self);

The handlers of GlobalDesignHook:

 // lookup root
 ChangeLookupRoot
   Called when the "LookupRoot" changed.
   The "LookupRoot" is the owner object of the currently selected components.
   Normally this is a TForm.
// methods CreateMethod GetMethodName GetMethods MethodExists RenameMethod ShowMethod Called MethodFromAncestor ChainCall
// components GetComponent GetComponentName GetComponentNames GetRootClassName ComponentRenamed Called when a component was renamed ComponentAdded Called when a new component was added to the LookupRoot ComponentDeleting Called before a component is freed. DeleteComponent Called by the IDE to delete a component. GetSelectedComponents Get the current selection of components.
// persistent objects GetObject GetObjectName GetObjectNames
// modifing Modified Revert RefreshPropertyValues

[edit] Project events

These events are defined in unit LazIDEIntf.

 LazarusIDE.AddHandlerOnProjectClose
 LazarusIDE.AddHandlerOnProjectOpened
 LazarusIDE.AddHandlerOnSavedAll
 LazarusIDE.AddHandlerOnSavingAll

[edit] Current Project

The current main project can be obtained by LazarusIDE.ActiveProject. (unit LazIDEIntf)

[edit] All units of current project

To iterate through all pascal units of the current main project of the IDE you can use for example:

 
uses LCLProc, FileUtil, LazIDEIntf, ProjectIntf;
 
procedure ListProjectUnits;
var
  LazProject: TLazProject;
  i: Integer;
  LazFile: TLazProjectFile;
begin
  LazProject:=LazarusIDE.ActiveProject;
  if LazProject<>nil then
    for i:=0 to LazProject.FileCount-1 do
    begin
      LazFile:=LazProject.Files[i];
      if LazFile.IsPartOfProject
      and FilenameIsPascalUnit(LazFile.Filename)
      then
        debugln(LazFile.Filename);
    end;
end;
 

[edit] The .lpr, .lpi and .lps file of a project

 
uses LCLProc, FileUtil, ProjectIntf, LazIDEIntf;
var
  LazProject: TLazProject;
begin
  LazProject:=LazarusIDE.ActiveProject;
  // every project has a .lpi file:
  DebugLn(['Project'' lpi file: ',LazProject.ProjectInfoFile]);
 
  // if the project session information is stored in a separate .lps file:
  if LazProject.SessionStorage<>pssNone then
    DebugLn(['Project'' lps file: ',LazProject.ProjectSessionFile]);
 
  // If the project has a .lpr file it is the main source file:
  if (LazProject.MainFile<>nil)
  and (CompareFileExt(LazProject.MainFile.Filename,'lpr')=0) then
    DebugLn(['Project has lpr file: ',LazProject.MainFile.Filename]);
end;
 

[edit] Adding a resource directive to a file

This adds a {$R example.res} to a pascal unit:

 
procedure AddResourceDirectiveToPascalSource(const Filename: string);
var
  ExpandedFilename: String;
  CodeBuf: TCodeBuffer;
begin
  // make sure the filename is trimmed and contains a full path
  ExpandedFilename:=CleanAndExpandFilename(Filename);
 
  // save changes in source editor to codetools
  LazarusIDE.SaveSourceEditorChangesToCodeCache(-1);
 
  // load the file
  CodeBuf:=CodeToolBoss.LoadFile(ExpandedFilename,true,false);
 
  // add the resource directive
  if not CodeToolBoss.AddResourceDirective(CodeBuf,'example.res') then
    LazarusIDE.DoJumpToCodeToolBossError;
end;
 

The codetools provides also functions like FindResourceDirective and RemoveDirective.

[edit] Adding help for sources

First create a THelpDatabase:

 HelpDB:=TFPDocHTMLHelpDatabase(
    HelpDatabases.CreateHelpDatabase('ANameOfYourChoiceForTheDatabase',
                                            TFPDocHTMLHelpDatabase,true));
 HelpDB.DefaultBaseURL:='http://your.help.org/';
 FPDocNode:=THelpNode.CreateURL(HelpDB,
                  'Package1 - A new package',
                  'file://index.html');
 HelpDB.TOCNode:=THelpNode.Create(HelpDB,FPDocNode);// once as TOC
 DirectoryItem:=THelpDBISourceDirectory.Create(FPDocNode,'$(PkgDir)/lcl',
                                 '*.pp;*.pas',false);// and once as normal page
 HelpDB.RegisterItem(DirectoryItem);

[edit] Original contributors and changes

This page has been converted from the epikwiki version.

This document was authored by Mattias Gaertner Initial import and formatted for Lazarus-CCR - VlxAdmin 9/26/2003