/ide/compatibilityrestrictions.pas
http://github.com/graemeg/lazarus · Pascal · 387 lines · 283 code · 69 blank · 35 comment · 30 complexity · 15f2f0c734bcf42c72f959b16a874b87 MD5 · raw file
- { /***************************************************************************
- CompatibilityRestrictions.pas - Lazarus IDE unit
- --------------------------------------------------
- ***************************************************************************/
- ***************************************************************************
- * *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- * *
- ***************************************************************************
- Abstract:
- Compatiblity restrictions utilities
- }
- unit CompatibilityRestrictions;
- {$mode objfpc}{$H+}
- interface
- uses
- Classes, SysUtils, Forms, LCLProc, InterfaceBase, StringHashList,
- Laz2_DOM, Laz2_XMLRead, Laz2_XMLWrite,
- ObjectInspector, OIFavoriteProperties, PackageIntf,
- PackageSystem, PackageDefs, ComponentReg, LazConf;
- type
- TReadRestrictedEvent = procedure (const RestrictedName, WidgetSetName: String) of object;
- TReadRestrictedContentEvent = procedure (const Short, Description: String) of object;
- PRestriction = ^TRestriction;
- TRestriction = record
- Name: String;
- Short: String;
- Description: String;
- WidgetSet: TLCLPlatform;
- end;
-
- { TClassHashList }
- TClassHashList = class
- private
- FHashList: TStringHashList;
- public
- constructor Create;
- destructor Destroy; override;
-
- procedure Add(const AClass: TPersistentClass);
- procedure AddComponent(const AClass: TComponentClass);
- function Find(const AClassName: String): TPersistentClass;
- end;
-
- TRestrictedList = array of TRestriction;
- { TRestrictedManager }
- TRestrictedManager = class
- private
- FRestrictedProperties: TOIRestrictedProperties;
- FRestrictedList: TRestrictedList;
- FRestrictedFiles: TStringList;
- FClassList: TClassHashList;
- procedure AddPackage(APackage: TLazPackageID);
- procedure AddRestricted(const RestrictedName, WidgetSetName: String);
- procedure AddRestrictedContent(const Short, Description: String);
- procedure AddRestrictedProperty(const RestrictedName, WidgetSetName: String);
- procedure GatherRestrictedFiles;
- procedure ReadRestrictions(const Filename: String;
- OnReadRestricted: TReadRestrictedEvent;
- OnReadRestrictedContent: TReadRestrictedContentEvent);
- public
- constructor Create;
- destructor Destroy; override;
-
- function GetRestrictedProperties: TOIRestrictedProperties;
- function GetRestrictedList: TRestrictedList;
- end;
-
- function GetRestrictedProperties: TOIRestrictedProperties;
- function GetRestrictedList: TRestrictedList;
-
- implementation
- var
- RestrictedManager: TRestrictedManager = nil;
-
- { TClassHashList }
- constructor TClassHashList.Create;
- begin
- inherited;
-
- FHashList := TStringHashList.Create(False);
- end;
- destructor TClassHashList.Destroy;
- begin
- FHashList.Free;
-
- inherited;
- end;
- procedure TClassHashList.Add(const AClass: TPersistentClass);
- var
- C: TClass;
- begin
- C := AClass;
- while (C <> nil) and (FHashList.Find(C.ClassName) < 0) do
- begin
- FHashList.Add(C.ClassName, Pointer(C));
- if (C = TPersistent) then Break;
- C := C.ClassParent;
- end;
- end;
- procedure TClassHashList.AddComponent(const AClass: TComponentClass);
- begin
- Add(AClass);
- end;
- function TClassHashList.Find(const AClassName: String): TPersistentClass;
- begin
- Result := TPersistentClass(FHashList.Data[AClassName]);
- end;
- function GetRestrictedProperties: TOIRestrictedProperties;
- begin
- if RestrictedManager = nil then
- RestrictedManager := TRestrictedManager.Create;
- Result := RestrictedManager.GetRestrictedProperties;
- end;
- function GetRestrictedList: TRestrictedList;
- begin
- if RestrictedManager = nil then
- RestrictedManager := TRestrictedManager.Create;
- Result := RestrictedManager.GetRestrictedList;
- end;
- { TRestrictedManager }
- function TRestrictedManager.GetRestrictedProperties: TOIRestrictedProperties;
- var
- I: Integer;
- begin
- Result := nil;
- FreeAndNil(FRestrictedProperties);
- FRestrictedProperties := TOIRestrictedProperties.Create;
- FClassList := TClassHashList.Create;
- try
- IDEComponentPalette.IterateRegisteredClasses(@(FClassList.AddComponent));
- FClassList.Add(TForm);
- FClassList.Add(TDataModule);
-
- for I := 0 to FRestrictedFiles.Count - 1 do
- ReadRestrictions(FRestrictedFiles[I], @AddRestrictedProperty, nil);
-
- Result := FRestrictedProperties;
- finally
- FreeAndNil(FClassList);
- end;
- end;
- function TRestrictedManager.GetRestrictedList: TRestrictedList;
- var
- I: Integer;
- begin
- SetLength(FRestrictedList, 0);
- for I := 0 to FRestrictedFiles.Count - 1 do
- ReadRestrictions(FRestrictedFiles[I], @AddRestricted, @AddRestrictedContent);
-
- Result := FRestrictedList;
- end;
- procedure TRestrictedManager.AddPackage(APackage: TLazPackageID);
- var
- ALazPackage: TLazPackage;
- I: Integer;
- begin
- if APackage = nil then Exit;
- ALazPackage := PackageGraph.FindPackageWithID(APackage);
- if ALazPackage = nil then Exit;
-
- for I := 0 to ALazPackage.FileCount - 1 do
- if ALazPackage.Files[I].FileType = pftIssues then
- FRestrictedFiles.Add(ALazPackage.Files[I].GetFullFilename);
- end;
- procedure TRestrictedManager.AddRestricted(const RestrictedName, WidgetSetName: String);
- begin
- SetLength(FRestrictedList, Succ(Length(FRestrictedList)));
- FRestrictedList[High(FRestrictedList)].Name := RestrictedName;
- FRestrictedList[High(FRestrictedList)].WidgetSet := DirNameToLCLPlatform(WidgetSetName);
- FRestrictedList[High(FRestrictedList)].Short := '';
- FRestrictedList[High(FRestrictedList)].Description := '';
- end;
- procedure TRestrictedManager.AddRestrictedContent(const Short, Description: String);
- begin
- if Length(FRestrictedList) = 0 then Exit;
- FRestrictedList[High(FRestrictedList)].Short := Short;
- FRestrictedList[High(FRestrictedList)].Description := Description;
- end;
- procedure TRestrictedManager.AddRestrictedProperty(const RestrictedName, WidgetSetName: String);
- var
- Issue: TOIRestrictedProperty;
- AClass: TPersistentClass;
- AProperty: String;
- P: Integer;
- begin
- if RestrictedName = '' then Exit;
- P := Pos('.', RestrictedName);
- if P = 0 then
- begin
- AClass := FClassList.Find(RestrictedName);
- AProperty := '';
- end
- else
- begin
- AClass := FClassList.Find(Copy(RestrictedName, 0, P - 1));
- AProperty := Copy(RestrictedName, P + 1, MaxInt);
- end;
-
- if AClass = nil then
- begin
- // add as generic widgetset issue
- FRestrictedProperties.WidgetSetRestrictions[DirNameToLCLPlatform(WidgetSetName)] := FRestrictedProperties.WidgetSetRestrictions[DirNameToLCLPlatform(WidgetSetName)] + 1;
- Exit;
- end;
-
- Issue := TOIRestrictedProperty.Create(AClass, AProperty, True);
- Issue.WidgetSets := [DirNameToLCLPlatform(WidgetSetName)];
- FRestrictedProperties.Add(Issue);
- end;
- procedure TRestrictedManager.GatherRestrictedFiles;
- begin
- FRestrictedFiles.Clear;
- PackageGraph.IteratePackages([fpfSearchInInstalledPckgs], @AddPackage);
- end;
- procedure TRestrictedManager.ReadRestrictions(const Filename: String;
- OnReadRestricted: TReadRestrictedEvent;
- OnReadRestrictedContent: TReadRestrictedContentEvent);
- var
- IssueFile: TXMLDocument;
- R, N: TDOMNode;
-
- function ReadContent(ANode: TDOMNode): String;
- var
- S: TStringStream;
- N: TDOMNode;
- begin
- Result := '';
- S := TStringStream.Create('');
- try
- N := ANode.FirstChild;
- while N <> nil do
- begin
- WriteXML(N, S);
- N := N.NextSibling;
- end;
-
- Result := S.DataString;
- finally
- S.Free;
- end;
- end;
-
- procedure ParseWidgetSet(ANode: TDOMNode);
- var
- WidgetSetName, IssueName, Short, Description: String;
- IssueNode, AttrNode, IssueContentNode: TDOMNode;
- begin
- AttrNode := ANode.Attributes.GetNamedItem('name');
- if AttrNode <> nil then WidgetSetName := AttrNode.NodeValue
- else WidgetSetName := 'win32';
-
- IssueNode := ANode.FirstChild;
- while IssueNode <> nil do
- begin
- if IssueNode.NodeName = 'issue' then
- begin
- AttrNode := IssueNode.Attributes.GetNamedItem('name');
- if AttrNode <> nil then IssueName := AttrNode.NodeValue
- else IssueName := 'win32';
-
- if Assigned(OnReadRestricted) then
- OnReadRestricted(IssueName, WidgetSetName);
- if Assigned(OnReadRestrictedContent) then
- begin
- Short := '';
- Description := '';
-
- IssueContentNode := IssueNode.FirstChild;
- while IssueContentNode <> nil do
- begin
- if IssueContentNode.NodeName = 'short' then
- Short := ReadContent(IssueContentNode)
- else
- if IssueContentNode.NodeName = 'descr' then
- Description := ReadContent(IssueContentNode);
- IssueContentNode := IssueContentNode.NextSibling;
- end;
-
- OnReadRestrictedContent(Short, Description);
- end;
- end;
- IssueNode := IssueNode.NextSibling;
- end;
- end;
-
- begin
- try
- ReadXMLFile(IssueFile, Filename);
- except
- on E: Exception do
- DebugLn('TIssueManager.ReadFileIssues failed: ' + E.Message);
- end;
-
- try
- if IssueFile = nil then Exit;
- R := IssueFile.FindNode('package');
- if R = nil then Exit;
- N := R.FirstChild;
- while N <> nil do
- begin
- if N.NodeName = 'widgetset' then
- ParseWidgetSet(N);
- N := N.NextSibling;
- end;
- finally
- IssueFile.Free;
- end;
- end;
- constructor TRestrictedManager.Create;
- begin
- inherited;
-
- FRestrictedFiles := TStringList.Create;
- FRestrictedProperties := nil;
-
- GatherRestrictedFiles;
- end;
- destructor TRestrictedManager.Destroy;
- begin
- FreeAndNil(FRestrictedFiles);
- FreeAndNil(FRestrictedProperties);
-
- inherited Destroy;
- end;
- finalization
- FreeAndNil(RestrictedManager);
- end.