Extending the IDE/ru

From Free Pascal wiki
Jump to: navigation, search

Deutsch (de) English (en) español (es) français (fr) 日本語 (ja) русский (ru) slovenčina (sk) 中文(中国大陆)‎ (zh_CN)

Расширения среды разработки (IDE)

Обзор

Среда разработки (IDE) поддерживает несколько типов плагинов:

Компоненты (Components) 
Это элементы палитры компонентов. Например, TButton может быть использован для создания кнопок.
Редакторы компонентов (Component Editors) 
Редакторы компонентов используются когда вы выполняете двойной клик на компоненте в дизайнере формы или добавляете несколько новых пунктов в всплывающее меню дизайнера, когда вы нажимаете правую кнопку мыши в дизайнере формы.
Редакторы свойств (Property Editors) 
Эти редакторы используются в инспекторе объектов.
Эксперты (Experts) 
Все прочие плагины.


Существует две возможности добавить собственный плагин к среде разработке Lazarus:

  1. Написать пакет, установить его и зарегистрировать ваш плагин при помощи процедуры 'Register'.
  2. Дополнить код Lazarus и выслать вашу разницу SVN в список рассылки Lazarus.

Написание компонентов

Вы можете создавать новые компоненты при помощи редактора пакетов. Например: Создать или открыть пакет, нажать кнопку Добавить (Add), выбрать закладку Новый компонент (New Component), заполнить поля: Тип предка (Ancestor Type) = TButton, Новое имя класса (New class name) = TMyButton, Страница палитры (palette page) = Misc, Имя файла модуля (Unit file name) = mybutton.pas (этот файл будет создан), Имя модуля (unit name) MyButton и нажать кнопку ok.

Создание новому компоненту иконки для палитры компонентов

Например, необходимо создать иконмку для компонента TMyButton. Создаём графический файл форматов .bmp, .xpm или .png с таким же именем, что и имя класса компонента. Например tmybutton.png и сохраняем в каталоге и исходниками пакета. Картинка может быть создана любой графической программой (например gimp) и должна быть не больше чем 24x24 точки. После этого конвертируем картинку в файл ресурса .lrs при помощи инструмента lazres, который можно найти в каталоге lazarus/tools:

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

Эта операция создаст файл, который нужно будет включить в секцию инициализации вашего модуля mybutton.pas:

 initialization
   {$I mybutton.lrs}

Установите пакет.

Написание редактора компонента

ToDo Подсказка: смотри файл componenteditors.pas для примера

Написание редактора свойств

ToDo Hint: смотри файл propedits.pp for для примера

Регистрация обработчика событий

Существует некоторое количество событий в среде разработки (IDE), для который плагины могут добавлять свои собственные обработчики.

События дизайнера (Designer events)

В модуле propedits.pp имеется объект "GlobalDesignHook", который поддерживает несколько событий для дизайна. Каждое событие вызывает список обработчиков. Обработчики по умолчанию добавлены самой средой разработки (IDE). Вы можете добавить свои собственные обработчики при помощи методов AddHandlerXXX и RemoveHandlerXXX. Они будут вызваны прежде чем обработчики по умолчанию среды.

Примеры:

 Добавление ваших обработчиков (это обычно производится в конструкторе вашего объекта):
   GlobalDesignHook.AddHandlerComponentAdded(@YourOnComponentAdded);
Удаление вашего обработчика: GlobalDesignHook.RemoveHandlerComponentAdded(@YourOnComponentAdded);
Вы можете удалить все обработчики сразу. Например, это будет хорошей идеей добавить следующую строку в деструктор вашего объекта: GlobalDesignHook.RemoveAllHandlersForObject(Self);

Обработчики событий объекта GlobalDesignHook:

 // lookup root
 ChangeLookupRoot
   Вызывается, когда "LookupRoot" изменяется.
   "LookupRoot" - это объект владелец текущего выбранного компонента.
   Обычно это TForm.
// methods CreateMethod GetMethodName GetMethods MethodExists RenameMethod ShowMethod MethodFromAncestor ChainCall
// components GetComponent GetComponentName GetComponentNames GetRootClassName ComponentRenamed Вызывается, когда компонент был переименован ComponentAdded Вызывается когда новый компонент добавляется в LookupRoot ComponentDeleting Вызывается перед очисткой компонента. DeleteComponent Вызывается средой разработки (IDE) для того, чтобы удалить компонент. GetSelectedComponents Возвращает текущее выделение компонентов.
// persistent objects GetObject GetObjectName GetObjectNames
// modifing Modified Revert RefreshPropertyValues

События проекта (Project events)

Эти события определены в модуле LazIDEIntf.

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

Текущий проект (Current Project)

Текущий проект можно получить через LazarusIDE.ActiveProject. (модуль LazIDEIntf)

Все модули текущего проекта

Чтобы перебрать все паскалевские модули текущего проекта в среде разработки (IDE) вы можете использовать следующий пример:

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;

Служебные файлы .lpr, .lpi и .lps проекта

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;

Исполняемый файл / целевой файл проекта

Существует макро $(TargetFile), которым могут воспользоваться пути и врешние инструменты. Вы можете так же запросить этот макрос в коде:

uses MacroIntf;
 
function MyGetProjectTargetFile: string;
begin
  Result:='$(TargetFile)';
  if not IDEMacros.SubstituteMacros(Result) then
    raise Exception.Create('unable to retrieve target file of project');
end;

Добавление ваших собственных типов файлов

Вы можете добавлять свои собственный пункты в диалог 'Файл/Создать ...':

  • Смотрите модуль ProjectIntf пакета IDEIntf.
  • Выберите базовый класс TFileDescPascalUnit для обычных модулей или TFileDescPascalUnitWithResource для новый модулей форм/модулей данных.

Добавление нового типа файла

Этот пример из модуля ide/mainintf.pas регистрирует простой текстовый файл:

uses ProjectIntf;
...
  { TFileDescText }
 
  TFileDescMyText = class(TProjectFileDescriptor)
  public
    constructor Create; override;
    function GetLocalizedName: string; override;
    function GetLocalizedDescription: string; override;
  end;
...
 
procedure Register;
 
implementation
 
procedure Register;
begin
  RegisterProjectFileDescriptor(TFileDescMyText.Create,FileDescGroupName);
end;
 
{ TFileDescMyText }
 
constructor TFileDescMyText.Create;
begin
  inherited Create;
  Name:='MyText'; // do not translate this
  DefaultFilename:='text.txt';
  AddToProject:=false;
end;
 
function TFileDescText.GetLocalizedName: string;
begin
  Result:='My Text'; // replace this with a resourcestring
end;
 
function TFileDescText.GetLocalizedDescription: string;
begin
  Result:='An empty text file';
end;

Add a new form type

This example is from the ide/mainintf.pas and registers the normal form:

uses ProjectIntf,FormEditingIntf ;
 
...
  TFileDescPascalUnitWithMyForm = class(TFileDescPascalUnitWithResource)
  public
    constructor Create; override;
    function GetInterfaceUsesSection: string; override;
    function GetLocalizedName: string; override;
    function GetLocalizedDescription: string; override;
  end;
...
 
procedure Register;
 
implementation
 
procedure Register;
begin
  RegisterProjectFileDescriptor(TFileDescPascalUnitWithMyForm.Create,FileDescGroupName);
  FormEditingHook.RegisterDesignerBaseClass(TMyForm);    
end;
 
{ TFileDescPascalUnitWithMyForm }
 
constructor TFileDescPascalUnitWithMyForm.Create;
begin
  inherited Create;
  Name:='MyForm'; // do not translate this
  ResourceClass:=TMyForm;
  UseCreateFormStatements:=true;
end;
 
function TFileDescPascalUnitWithMyForm.GetInterfaceUsesSection: string;
begin
  Result:='Classes, SysUtils, MyWidgetSet';
end;
 
function TFileDescPascalUnitWithForm.GetLocalizedName: string;
begin
  Result:='MyForm'; // replace this with a resourcestring
end;
 
function TFileDescPascalUnitWithForm.GetLocalizedDescription: string;
begin
  Result:='Create a new MyForm from example package NotLCLDesigner';
end;

CodeTools в среде разработки (IDE)

Прежде чем использовать codetools вам необходимо сохранить ваши текущие изменения в редакторе кода в буферах codetool:

uses LazIDEIntf;
...
  // save changes in source editor to codetools
  LazarusIDE.SaveSourceEditorChangesToCodeCache(-1); // -1: commit all source editors

Добавление директивы ресурсов в файл

Этот пример добавляет {$R example.res} в паскалевский модуль:

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;

Утилиты codetools так же предоставляют функции вроде FindResourceDirective и RemoveDirective.

Добавление помощи к исходникам

Сначала создаём 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);