Browse Source

ADD: Allow SynUniSyn change colors

Alexander Koblov 3 years ago
parent
commit
06498ad1a0

+ 14 - 2
components/synunihighlighter/source/SynUniClasses.pas

@@ -104,6 +104,7 @@ type
     ParentBackground: boolean;
     ParentBackground: boolean;
     constructor Create(Name: string);
     constructor Create(Name: string);
 //    destructor Destroy(); override;
 //    destructor Destroy(); override;
+    function GetHashCode: PtrInt; override;
     procedure LoadFromString(Value: string);
     procedure LoadFromString(Value: string);
     procedure SaveToStream(StreamWriter: TStreamWriter);
     procedure SaveToStream(StreamWriter: TStreamWriter);
   end;
   end;
@@ -199,7 +200,7 @@ const
 implementation
 implementation
 
 
 uses
 uses
-  Laz2_XMLRead;
+  Crc, Laz2_XMLRead;
 
 
 function StrToSet(st: string): TSymbSet;
 function StrToSet(st: string): TSymbSet;
 var i: integer;
 var i: integer;
@@ -386,7 +387,7 @@ begin
 
 
     WriteTag(Ind+2, 'General');
     WriteTag(Ind+2, 'General');
     WriteParam('Name',       General.Name);
     WriteParam('Name',       General.Name);
-    WriteParam('Extensions', General.Extensions, CloseEmptyTag);
+    WriteParam('Extensions', General.Extensions);
     WriteParam('Other',      BoolToStr(General.Other), CloseEmptyTag);
     WriteParam('Other',      BoolToStr(General.Other), CloseEmptyTag);
 
 
     WriteTag(Ind+2, 'Author');
     WriteTag(Ind+2, 'Author');
@@ -505,6 +506,17 @@ begin
 //  UseStyle := False;
 //  UseStyle := False;
 end;
 end;
 
 
+function TSynAttributes.GetHashCode: PtrInt;
+var
+  ACrc: Cardinal = 0;
+begin
+  ACrc:= CRC32(ACrc, @Background, SizeOf(TColor));
+  ACrc:= CRC32(ACrc, @Foreground, SizeOf(TColor));
+  ACrc:= CRC32(ACrc, @Style, SizeOf(TFontStyles));
+  ACrc:= CRC32(ACrc, @ParentForeground, SizeOf(Boolean));
+  Result:= PtrInt(CRC32(ACrc, @ParentBackground, SizeOf(Boolean)));
+end;
+
 {destructor TSynAttributes.Destroy;
 {destructor TSynAttributes.Destroy;
 //var xml: TXMLParser;
 //var xml: TXMLParser;
 begin
 begin

+ 87 - 1
components/synunihighlighter/source/SynUniHighlighter.pas

@@ -57,6 +57,8 @@ type
 
 
   TSynUniSyn = class(TSynCustomHighlighter)
   TSynUniSyn = class(TSynCustomHighlighter)
   private
   private
+    FFileName: String;
+
     procedure ReadSyntax(Reader: TReader);
     procedure ReadSyntax(Reader: TReader);
     procedure WriteSyntax(Writer: TWriter);
     procedure WriteSyntax(Writer: TWriter);
   protected
   protected
@@ -84,11 +86,15 @@ type
     procedure DefineProperties(Filer: TFiler); override;
     procedure DefineProperties(Filer: TFiler); override;
     function GetSampleSource: string; override;
     function GetSampleSource: string; override;
     procedure SetSampleSource(Value: string); override;
     procedure SetSampleSource(Value: string); override;
+    function GetDefaultFilter: string; override;
+    procedure SetDefaultFilter(Value: string); override;
   public
   public
     class function GetLanguageName: string; override;
     class function GetLanguageName: string; override;
   public
   public
     constructor Create(AOwner: TComponent); overload; override;
     constructor Create(AOwner: TComponent); overload; override;
     destructor Destroy; override;
     destructor Destroy; override;
+    function GetHashCode: PtrInt; override;
+    procedure Assign(Source: TPersistent); override;
     function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
     function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
       override; {Abstract}
       override; {Abstract}
     function GetEol: Boolean; override; {Abstract}
     function GetEol: Boolean; override; {Abstract}
@@ -131,6 +137,7 @@ type
     Styles: TSynUniStyles;
     Styles: TSynUniStyles;
     SchemeFileName: string;
     SchemeFileName: string;
     SchemeName: string;
     SchemeName: string;
+    property FileName: String read FFileName;
     property MainRules: TSynRange read fMainRules;
     property MainRules: TSynRange read fMainRules;
     property SchemesList: TStringList read fSchemes write fSchemes; //Vitalik 2004
     property SchemesList: TStringList read fSchemes write fSchemes; //Vitalik 2004
     property SchemeIndex: integer read fSchemeIndex write fSchemeIndex; //Vitalik 2004
     property SchemeIndex: integer read fSchemeIndex write fSchemeIndex; //Vitalik 2004
@@ -186,6 +193,55 @@ begin
   inherited;
   inherited;
 end;
 end;
 
 
+function TSynUniSyn.GetHashCode: PtrInt;
+
+  function Update(ACrc: PtrInt; ARule: TSynRule): PtrInt;
+  var
+    Index: Integer;
+  begin
+    Result:= ACrc xor ARule.Attribs.GetHashCode;
+
+    if ARule is TSynRange then
+    begin
+      with TSynRange(ARule) do
+      begin
+        for Index := 0 to SetCount - 1 do
+          Result:= Update(Result, Sets[Index]);
+        for Index := 0 to RangeCount - 1 do
+          Result:= Update(Result, Ranges[Index]);
+        for Index := 0 to KeyListCount - 1 do
+          Result:= Update(Result, KeyLists[Index]);
+      end;
+    end;
+  end;
+
+begin
+  Result:= Update(0, MainRules);
+end;
+
+procedure TSynUniSyn.Assign(Source: TPersistent);
+var
+  AStream: TMemoryStream;
+begin
+  inherited Assign(Source);
+  if (Source is TSynUniSyn) then
+  begin
+    if GetHashCode <> Source.GetHashCode then
+    begin
+      AStream:= TMemoryStream.Create;
+      try
+        Tag:= -1;
+        TSynUniSyn(Source).SaveToStream(AStream);
+        AStream.Seek(0, soBeginning);
+        LoadFromStream(AStream, False);
+        Self.Info.Version.ReleaseDate:= Now;
+      finally
+        AStream.Free;
+      end;
+    end;
+  end;
+end;
+
 procedure TSynUniSyn.SetLine(const NewValue: string; LineNumber: Integer);
 procedure TSynUniSyn.SetLine(const NewValue: string; LineNumber: Integer);
 //: Set current line in SynEdit for highlighting
 //: Set current line in SynEdit for highlighting
   function HaveNodeAnyStart(Node: TSymbolNode): boolean;
   function HaveNodeAnyStart(Node: TSymbolNode): boolean;
@@ -352,7 +408,7 @@ begin
   until (fLine[Run] > #32) or (fLine[Run] in [#0, #10, #13]);
   until (fLine[Run] > #32) or (fLine[Run] in [#0, #10, #13]);
 end;
 end;
 
 
-function TSynUniSyn.IsKeyword(const aKeyword: string): boolean;
+function TSynUniSyn.IsKeyword(const AKeyword: string): boolean;
 //! Never used!!!! ??? SSS
 //! Never used!!!! ??? SSS
 begin
 begin
   // Result := fSymbols.FindSymbol(aKeyword) <> nil;
   // Result := fSymbols.FindSymbol(aKeyword) <> nil;
@@ -613,6 +669,35 @@ begin
   Info.Sample.Text := Value;
   Info.Sample.Text := Value;
 end;
 end;
 
 
+function TSynUniSyn.GetDefaultFilter: string;
+var
+  S: String;
+begin
+  Result:= EmptyStr;
+  for S in Info.General.Extensions.Split([' ', ',']) do
+  begin
+    Result+= '*.' + S + ';';
+  end;
+  if Length(Result) > 0 then Result:= Info.General.Name + '|' + Copy(Result, 1, Length(Result) - 1);
+end;
+
+procedure TSynUniSyn.SetDefaultFilter(Value: string);
+var
+  S: String;
+  Result: String;
+begin
+  Result:= EmptyStr;
+  Value:= Copy(Value, Pos('|', Value) + 1, MaxInt);
+  for S in Value.Split([';']) do
+  begin
+    Result+= StringReplace(S, '*.', '', []) + ',';
+  end;
+  if Length(Result) = 0 then
+    Info.General.Extensions:= EmptyStr
+  else
+    Info.General.Extensions:= Copy(Result, 1, Length(Result) - 1);
+end;
+
 procedure TSynUniSyn.LoadFromXml(xml: TDOMNode);
 procedure TSynUniSyn.LoadFromXml(xml: TDOMNode);
 var
 var
   i, J, K: integer;
   i, J, K: integer;
@@ -728,6 +813,7 @@ end;
 
 
 procedure TSynUniSyn.LoadFromFile(FileName: string);
 procedure TSynUniSyn.LoadFromFile(FileName: string);
 begin
 begin
+  FFileName:= FileName;
   LoadFromStream(TFileStreamUTF8.Create(FileName, fmOpenRead or fmShareDenyNone));
   LoadFromStream(TFileStreamUTF8.Create(FileName, fmOpenRead or fmShareDenyNone));
 end;
 end;
 
 

+ 1 - 1
components/synunihighlighter/synuni.lpk

@@ -37,7 +37,7 @@ https://www.mozilla.org/en-US/MPL/1.1/
 or
 or
 GNU General Public License, version 2
 GNU General Public License, version 2
 https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html"/>
 https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html"/>
-    <Version Major="1" Minor="8"/>
+    <Version Major="1" Minor="8" Release="1"/>
     <Files Count="3">
     <Files Count="3">
       <Item1>
       <Item1>
         <Filename Value="source/SynUniClasses.pas"/>
         <Filename Value="source/SynUniClasses.pas"/>

+ 50 - 22
src/dmhigh.pas

@@ -53,6 +53,7 @@ type
   private
   private
     FTemp: Boolean;
     FTemp: Boolean;
     FChanged: Boolean;
     FChanged: Boolean;
+    procedure SaveUniHighlighters;
     procedure ImportFromOldFormat;
     procedure ImportFromOldFormat;
   public
   public
     SynHighlighterList: TStringList;
     SynHighlighterList: TStringList;
@@ -89,9 +90,8 @@ type
   TSynHighlighterAttributesHelper = class helper for TSynHighlighterAttributes
   TSynHighlighterAttributesHelper = class helper for TSynHighlighterAttributes
   private
   private
     function GetFeatures: TSynHighlighterAttrFeatures;
     function GetFeatures: TSynHighlighterAttrFeatures;
-    procedure SetFeatures(AValue: TSynHighlighterAttrFeatures);
   public
   public
-    property Features: TSynHighlighterAttrFeatures read GetFeatures write SetFeatures;
+    property Features: TSynHighlighterAttrFeatures read GetFeatures;
   end;
   end;
 
 
 var
 var
@@ -102,8 +102,9 @@ implementation
 {$R *.lfm}
 {$R *.lfm}
 
 
 uses
 uses
-  Graphics, SynEditTypes, FileUtil, uHighlighterProcs, DCXmlConfig, uGlobsPaths,
-  DCClassesUtf8, LazUTF8Classes, DCOSUtils, DCStrUtils, uLng, uMasks, uGlobs, uOSUtils;
+  Graphics, SynEditTypes, SynUniClasses, FileUtil, uHighlighterProcs, DCXmlConfig,
+  uGlobsPaths, DCClassesUtf8, LazUTF8Classes, DCOSUtils, DCStrUtils, uLng, uMasks,
+  uGlobs, uOSUtils;
 
 
 const
 const
   csDefaultName = 'editor.col';
   csDefaultName = 'editor.col';
@@ -191,7 +192,6 @@ begin
     SynHighlighterHashList.Add(HighLighter.LanguageName, HighLighter);
     SynHighlighterHashList.Add(HighLighter.LanguageName, HighLighter);
     with HighLighter.AddSpecialAttribute(rsSynDefaultText, SYNS_XML_DefaultText) do
     with HighLighter.AddSpecialAttribute(rsSynDefaultText, SYNS_XML_DefaultText) do
     begin
     begin
-      Features:= [hafBackColor, hafForeColor];
       Background:= clWindow;
       Background:= clWindow;
       Foreground:= clWindowText;
       Foreground:= clWindowText;
     end;
     end;
@@ -213,12 +213,43 @@ end;
 procedure TdmHighl.dmHighlDestroy(Sender: TObject);
 procedure TdmHighl.dmHighlDestroy(Sender: TObject);
 begin
 begin
   if FChanged and (FTemp = False) then
   if FChanged and (FTemp = False) then
+  begin
+    SaveUniHighlighters;
     SaveToFile(gpCfgDir + HighlighterConfig);
     SaveToFile(gpCfgDir + HighlighterConfig);
+  end;
   SynHighlighterList.Free;
   SynHighlighterList.Free;
   SynHighlighterHashList.Free;
   SynHighlighterHashList.Free;
   SynPlainTextHighlighter.Free;
   SynPlainTextHighlighter.Free;
 end;
 end;
 
 
+procedure TdmHighl.SaveUniHighlighters;
+var
+  I: Integer;
+  SynUniSyn: TSynUniSyn;
+  APath, AFileName: String;
+begin
+  if not gUseConfigInProgramDir then begin
+    APath:= IncludeTrailingBackslash(GetAppDataDir) + 'highlighters' + PathDelim;
+  end;
+  for I := 0 to SynHighlighterList.Count - 1 do
+  begin
+    if SynHighlighterList.Objects[I] is TSynUniSyn then
+    begin
+      SynUniSyn:= TSynUniSyn(SynHighlighterList.Objects[I]);
+      if SynUniSyn.Tag < 0 then
+      begin
+        if gUseConfigInProgramDir then
+          AFileName:= SynUniSyn.FileName
+        else begin
+          AFileName:= APath + ExtractFileName(SynUniSyn.FileName);
+        end;
+        SynUniSyn.SaveToFile(AFileName);
+        SynUniSyn.Tag:= 0;
+      end;
+    end;
+  end;
+end;
+
 procedure TdmHighl.ImportFromOldFormat;
 procedure TdmHighl.ImportFromOldFormat;
 var
 var
   I: Integer = 0;
   I: Integer = 0;
@@ -356,13 +387,7 @@ var
     TargetHighlighter.DefaultFilter:= SourceHighlighter.DefaultFilter;
     TargetHighlighter.DefaultFilter:= SourceHighlighter.DefaultFilter;
     for J:= 0 to SourceHighlighter.AttrCount - 1 do
     for J:= 0 to SourceHighlighter.AttrCount - 1 do
     begin
     begin
-      TargetHighlighter.Attribute[J].Background:= SourceHighlighter.Attribute[J].Background;
-      TargetHighlighter.Attribute[J].Foreground:= SourceHighlighter.Attribute[J].Foreground;
-      TargetHighlighter.Attribute[J].FrameColor:= SourceHighlighter.Attribute[J].FrameColor;
-      TargetHighlighter.Attribute[J].FrameStyle:= SourceHighlighter.Attribute[J].FrameStyle;
-      TargetHighlighter.Attribute[J].FrameEdges:= SourceHighlighter.Attribute[J].FrameEdges;
-      TargetHighlighter.Attribute[J].Style     := SourceHighlighter.Attribute[J].Style;
-      TargetHighlighter.Attribute[J].StyleMask := SourceHighlighter.Attribute[J].StyleMask;
+      TargetHighlighter.Attribute[J].Assign(SourceHighlighter.Attribute[J]);
     end;
     end;
   end;
   end;
 
 
@@ -370,9 +395,13 @@ begin
   FChanged:= True;
   FChanged:= True;
   for I:= 0 to SynHighlighterList.Count - 1 do
   for I:= 0 to SynHighlighterList.Count - 1 do
   begin
   begin
-    CopyAttributes(TSynCustomHighlighter(Highl.SynHighlighterList.Objects[I]),
-                   TSynCustomHighlighter(SynHighlighterList.Objects[I])
-                  );
+    if Highl.SynHighlighterList.Objects[I] is TSynUniSyn then
+      TSynUniSyn(SynHighlighterList.Objects[I]).Assign(TSynUniSyn(Highl.SynHighlighterList.Objects[I]))
+
+    else
+      CopyAttributes(TSynCustomHighlighter(Highl.SynHighlighterList.Objects[I]),
+                     TSynCustomHighlighter(SynHighlighterList.Objects[I])
+                    );
   end;
   end;
 end;
 end;
 
 
@@ -563,13 +592,12 @@ function TSynHighlighterAttributesHelper.GetFeatures: TSynHighlighterAttrFeature
 begin
 begin
   if SameText(StoredName, SYNS_XML_DefaultText) then
   if SameText(StoredName, SYNS_XML_DefaultText) then
     Result:= [hafBackColor, hafForeColor]
     Result:= [hafBackColor, hafForeColor]
-  else
-    Result:= [hafBackColor, hafForeColor, hafFrameColor, hafStyle, hafFrameStyle, hafFrameEdges];
-end;
-
-procedure TSynHighlighterAttributesHelper.SetFeatures(AValue: TSynHighlighterAttrFeatures);
-begin
-
+  else begin
+    if Self is TSynAttributes then
+      Result:= [hafBackColor, hafForeColor, hafStyle]
+    else
+      Result:= [hafBackColor, hafForeColor, hafFrameColor, hafStyle, hafFrameStyle, hafFrameEdges];
+  end;
 end;
 end;
 
 
 end.
 end.

+ 132 - 32
src/frames/foptionseditorcolors.pas

@@ -31,7 +31,7 @@ interface
 uses
 uses
   Classes, SysUtils, FileUtil, SynEdit, Forms, Controls, StdCtrls, ExtCtrls,
   Classes, SysUtils, FileUtil, SynEdit, Forms, Controls, StdCtrls, ExtCtrls,
   ColorBox, ComCtrls, Dialogs, Menus, Buttons, fOptionsFrame, DividerBevel, types,
   ColorBox, ComCtrls, Dialogs, Menus, Buttons, fOptionsFrame, DividerBevel, types,
-  Graphics, SynEditHighlighter, dmHigh;
+  Graphics, SynEditHighlighter, SynUniClasses, SynUniRules, dmHigh;
 
 
 type
 type
 
 
@@ -113,6 +113,9 @@ type
     FIsEditingDefaults: Boolean;
     FIsEditingDefaults: Boolean;
     UpdatingColor: Boolean;
     UpdatingColor: Boolean;
     procedure UpdateCurrentScheme;
     procedure UpdateCurrentScheme;
+    function TreeAddSet(Node: TTreeNode; SymbSet: TSynSet): TTreeNode;
+    function TreeAddRange(Node: TTreeNode; Range: TSynRange): TTreeNode;
+    function TreeAddKeyList(Node: TTreeNode; KeyList: TSynKeyList): TTreeNode;
     function SynAttributeSortCompare(Node1, Node2: TTreeNode): Integer;
     function SynAttributeSortCompare(Node1, Node2: TTreeNode): Integer;
   protected
   protected
     procedure Init; override;
     procedure Init; override;
@@ -249,6 +252,7 @@ procedure TfrmOptionsEditorColors.cmbLanguageChange(Sender: TObject);
 var
 var
   I: LongInt;
   I: LongInt;
   ANode: TTreeNode;
   ANode: TTreeNode;
+  SynUniSyn: Boolean;
 begin
 begin
   if (cmbLanguage.ItemIndex < 0) then Exit;
   if (cmbLanguage.ItemIndex < 0) then Exit;
   FCurrentHighlighter:= TSynCustomHighlighter(cmbLanguage.Items.Objects[cmbLanguage.ItemIndex]);
   FCurrentHighlighter:= TSynCustomHighlighter(cmbLanguage.Items.Objects[cmbLanguage.ItemIndex]);
@@ -262,8 +266,17 @@ begin
     ColorPreview.Lines.Text:= EmptyStr;
     ColorPreview.Lines.Text:= EmptyStr;
   end;
   end;
   FHighl.SetHighlighter(ColorPreview, FCurrentHighlighter);
   FHighl.SetHighlighter(ColorPreview, FCurrentHighlighter);
+  SynUniSyn:= (FCurrentHighlighter is TSynUniSyn);
+  ColorElementTree.ShowButtons:= SynUniSyn;
+  ColorElementTree.ShowRoot:= SynUniSyn;
+  btnResetMask.Enabled:= not SynUniSyn;
   ColorElementTree.Items.Clear;
   ColorElementTree.Items.Clear;
-  if (FCurrentHighlighter.AttrCount > 0) then
+  if SynUniSyn then
+  begin
+    ANode:= TreeAddRange(nil, TSynUniSyn(FCurrentHighlighter).MainRules);
+    ANode.Expand(False);
+  end
+  else if (FCurrentHighlighter.AttrCount > 0) then
   begin
   begin
     for I:= 0 to FCurrentHighlighter.AttrCount - 1 do
     for I:= 0 to FCurrentHighlighter.AttrCount - 1 do
     begin
     begin
@@ -271,11 +284,11 @@ begin
       ANode.Data:= FCurrentHighlighter.Attribute[I];
       ANode.Data:= FCurrentHighlighter.Attribute[I];
     end;
     end;
     ColorElementTree.CustomSort(@SynAttributeSortCompare);
     ColorElementTree.CustomSort(@SynAttributeSortCompare);
-    if ColorElementTree.Items.GetFirstNode <> nil then
-    begin
-      ColorElementTree.Items.GetFirstNode.Selected := True;
-      ColorElementTreeChange(ColorElementTree, nil);
-    end;
+  end;
+  if ColorElementTree.Items.GetFirstNode <> nil then
+  begin
+    ColorElementTree.Items.GetFirstNode.Selected := True;
+    ColorElementTreeChange(ColorElementTree, ColorElementTree.Items.GetFirstNode);
   end;
   end;
 end;
 end;
 
 
@@ -330,29 +343,41 @@ var
   FullAbcWidth, AbcWidth: Integer;
   FullAbcWidth, AbcWidth: Integer;
   Attri: TSynHighlighterAttributes;
   Attri: TSynHighlighterAttributes;
   TextY: Integer;
   TextY: Integer;
+  AText: String;
   c: TColor;
   c: TColor;
   s: String;
   s: String;
 begin
 begin
-  if (ColorElementTree.Items.GetFirstNode = Node) and FIsEditingDefaults then
-    Attri := FDefHighlightElement
-  else
-    Attri := TSynHighlighterAttributes(Node.Data);
+  if not (TObject(Node.Data) is TSynHighlighterAttributes) then
+  begin
+    AText:= TSynRule(Node.Data).Name;
+    Attri := TSynRule(Node.Data).Attribs;
+  end
+  else begin
+    if (ColorElementTree.Items.GetFirstNode = Node) and FIsEditingDefaults then
+      Attri := FDefHighlightElement
+    else begin
+      Attri := TSynHighlighterAttributes(Node.Data);
+    end;
+    AText:= Attri.Name;
+  end;
 
 
   if (Attri = nil) then Exit;
   if (Attri = nil) then Exit;
 
 
   // Draw node background and name
   // Draw node background and name
-  if cdsSelected in State then begin
+  if cdsSelected in State then
+  begin
     ColorElementTree.Canvas.Brush.Color := ColorElementTree.SelectionColor;
     ColorElementTree.Canvas.Brush.Color := ColorElementTree.SelectionColor;
     ColorElementTree.Canvas.Font.Color := InvertColor(ColorElementTree.SelectionColor);
     ColorElementTree.Canvas.Font.Color := InvertColor(ColorElementTree.SelectionColor);
   end else begin
   end else begin
     ColorElementTree.Canvas.Brush.Color := ColorElementTree.Color;
     ColorElementTree.Canvas.Brush.Color := ColorElementTree.Color;
     ColorElementTree.Canvas.Font.Color := Font.Color;
     ColorElementTree.Canvas.Font.Color := Font.Color;
   end;
   end;
-  NodeRect := Node.DisplayRect(False);
+  NodeRect := Node.DisplayRect(True);
   FullAbcWidth := ColorElementTree.Canvas.TextExtent(COLOR_NODE_PREFIX).cx;
   FullAbcWidth := ColorElementTree.Canvas.TextExtent(COLOR_NODE_PREFIX).cx;
   TextY := (NodeRect.Top + NodeRect.Bottom - ColorElementTree.Canvas.TextHeight(Node.Text)) div 2;
   TextY := (NodeRect.Top + NodeRect.Bottom - ColorElementTree.Canvas.TextHeight(Node.Text)) div 2;
+  NodeRect.Right+= FullAbcWidth;
   ColorElementTree.Canvas.FillRect(NodeRect);
   ColorElementTree.Canvas.FillRect(NodeRect);
-  ColorElementTree.Canvas.TextOut(NodeRect.Left+FullAbcWidth, TextY, Attri.Name);
+  ColorElementTree.Canvas.TextOut(NodeRect.Left+FullAbcWidth, TextY, AText);
 
 
   // Draw preview box - Background
   // Draw preview box - Background
   c := clNone;
   c := clNone;
@@ -408,21 +433,37 @@ end;
 
 
 procedure TfrmOptionsEditorColors.ColorElementTreeChange(Sender: TObject; Node: TTreeNode); //+++
 procedure TfrmOptionsEditorColors.ColorElementTreeChange(Sender: TObject; Node: TTreeNode); //+++
 var
 var
+  ParentFore, ParentBack: Boolean;
   AttrToShow: TSynHighlighterAttributes;
   AttrToShow: TSynHighlighterAttributes;
   IsDefault, CanGlobal: Boolean;
   IsDefault, CanGlobal: Boolean;
+  ARule: TSynRule;
 begin
 begin
   if UpdatingColor or (ColorElementTree.Selected = nil) or (ColorElementTree.Selected.Data = nil) then
   if UpdatingColor or (ColorElementTree.Selected = nil) or (ColorElementTree.Selected.Data = nil) then
     Exit;
     Exit;
 
 
-  FCurHighlightElement:= TSynHighlighterAttributes(ColorElementTree.Selected.Data);
+  if (TObject(ColorElementTree.Selected.Data) is TSynHighlighterAttributes) then
+  begin
+    FCurHighlightElement:= TSynHighlighterAttributes(ColorElementTree.Selected.Data);
+    IsDefault := SameText(rsSynDefaultText, FCurHighlightElement.Name);
+    CanGlobal := (cmbLanguage.ItemIndex > 0) and IsDefault;
+    ParentFore:= False;
+    ParentBack:= False;
+  end
+  else begin
+    ARule:= TSynRule(ColorElementTree.Selected.Data);
+    ParentFore:= ARule.Attribs.ParentForeground;
+    ParentBack:= ARule.Attribs.ParentBackground;
+    FCurHighlightElement:= ARule.Attribs;
+    IsDefault := (Node.Level = 0);
+    CanGlobal := False;
+  end;
+
   UpdatingColor := True;
   UpdatingColor := True;
   DisableAlign;
   DisableAlign;
   try
   try
 
 
   FDefHighlightElement:= FHighl.SynPlainTextHighlighter.Attribute[FHighl.SynPlainTextHighlighter.AttrCount - 1];
   FDefHighlightElement:= FHighl.SynPlainTextHighlighter.Attribute[FHighl.SynPlainTextHighlighter.AttrCount - 1];
 
 
-  IsDefault := SameText(rsSynDefaultText, FCurHighlightElement.Name);
-  CanGlobal := (cmbLanguage.ItemIndex > 0) and IsDefault;
   FIsEditingDefaults:= CanGlobal and (FCurrentHighlighter.Tag = 1);
   FIsEditingDefaults:= CanGlobal and (FCurrentHighlighter.Tag = 1);
 
 
   tbtnGlobal.Enabled := CanGlobal;
   tbtnGlobal.Enabled := CanGlobal;
@@ -440,7 +481,7 @@ begin
   ForegroundColorBox.Style := ForegroundColorBox.Style + [cbIncludeDefault];
   ForegroundColorBox.Style := ForegroundColorBox.Style + [cbIncludeDefault];
   BackGroundColorBox.Style := BackGroundColorBox.Style + [cbIncludeDefault];
   BackGroundColorBox.Style := BackGroundColorBox.Style + [cbIncludeDefault];
 
 
-  // Forground
+  // Foreground
   ForeGroundLabel.Visible              := (hafForeColor in AttrToShow.Features) and
   ForeGroundLabel.Visible              := (hafForeColor in AttrToShow.Features) and
                                           (IsDefault = True);
                                           (IsDefault = True);
   ForeGroundUseDefaultCheckBox.Visible := (hafForeColor in AttrToShow.Features) and
   ForeGroundUseDefaultCheckBox.Visible := (hafForeColor in AttrToShow.Features) and
@@ -452,7 +493,8 @@ begin
     ForegroundColorBox.Tag := ForegroundColorBox.DefaultColorColor
     ForegroundColorBox.Tag := ForegroundColorBox.DefaultColorColor
   else
   else
     ForegroundColorBox.Tag := ForegroundColorBox.Selected;
     ForegroundColorBox.Tag := ForegroundColorBox.Selected;
-  ForeGroundUseDefaultCheckBox.Checked := ForegroundColorBox.Selected <> clDefault;
+  ForeGroundUseDefaultCheckBox.Checked := (ForegroundColorBox.Selected <> clDefault) and
+                                          (ParentFore = False);
 
 
   // BackGround
   // BackGround
   BackGroundLabel.Visible              := (hafBackColor in AttrToShow.Features) and
   BackGroundLabel.Visible              := (hafBackColor in AttrToShow.Features) and
@@ -466,7 +508,8 @@ begin
     BackGroundColorBox.Tag := BackGroundColorBox.DefaultColorColor
     BackGroundColorBox.Tag := BackGroundColorBox.DefaultColorColor
   else
   else
     BackGroundColorBox.Tag := BackGroundColorBox.Selected;
     BackGroundColorBox.Tag := BackGroundColorBox.Selected;
-  BackGroundUseDefaultCheckBox.Checked := BackGroundColorBox.Selected <> clDefault;
+  BackGroundUseDefaultCheckBox.Checked := (BackGroundColorBox.Selected <> clDefault) and
+                                          (ParentBack = False);
 
 
   // Frame
   // Frame
   FrameColorUseDefaultCheckBox.Visible := hafFrameColor in AttrToShow.Features;
   FrameColorUseDefaultCheckBox.Visible := hafFrameColor in AttrToShow.Features;
@@ -522,7 +565,7 @@ begin
       TextItalicRadioOff.Checked := True;
       TextItalicRadioOff.Checked := True;
 
 
     TextUnderlineCheckBox.Checked := (fsUnderline in AttrToShow.Style) or
     TextUnderlineCheckBox.Checked := (fsUnderline in AttrToShow.Style) or
-                                (fsUnderline in AttrToShow.StyleMask);
+                                     (fsUnderline in AttrToShow.StyleMask);
     TextUnderlineRadioPanel.Enabled := TextUnderlineCheckBox.Checked;
     TextUnderlineRadioPanel.Enabled := TextUnderlineCheckBox.Checked;
 
 
     if not(fsUnderline in AttrToShow.StyleMask) then
     if not(fsUnderline in AttrToShow.StyleMask) then
@@ -534,7 +577,7 @@ begin
       TextUnderlineRadioOff.Checked := True;
       TextUnderlineRadioOff.Checked := True;
 
 
     TextStrikeOutCheckBox.Checked := (fsStrikeOut in AttrToShow.Style) or
     TextStrikeOutCheckBox.Checked := (fsStrikeOut in AttrToShow.Style) or
-                                (fsStrikeOut in AttrToShow.StyleMask);
+                                     (fsStrikeOut in AttrToShow.StyleMask);
     TextStrikeOutRadioPanel.Enabled := TextStrikeOutCheckBox.Checked;
     TextStrikeOutRadioPanel.Enabled := TextStrikeOutCheckBox.Checked;
 
 
     if not(fsStrikeOut in AttrToShow.StyleMask) then
     if not(fsStrikeOut in AttrToShow.StyleMask) then
@@ -600,13 +643,40 @@ begin
     if Sender = ForeGroundUseDefaultCheckBox then TheColorBox := ForegroundColorBox;
     if Sender = ForeGroundUseDefaultCheckBox then TheColorBox := ForegroundColorBox;
     if Sender = BackGroundUseDefaultCheckBox then TheColorBox := BackGroundColorBox;
     if Sender = BackGroundUseDefaultCheckBox then TheColorBox := BackGroundColorBox;
     if Sender = FrameColorUseDefaultCheckBox then TheColorBox := FrameColorBox;
     if Sender = FrameColorUseDefaultCheckBox then TheColorBox := FrameColorBox;
-    if Assigned(TheColorBox) then begin
-      if TCheckBox(Sender).Checked then begin
+    if Assigned(TheColorBox) then
+    begin
+      if TCheckBox(Sender).Checked then
+      begin
         TheColorBox.Selected := TheColorBox.Tag;
         TheColorBox.Selected := TheColorBox.Tag;
+        if (AttrToEdit is TSynAttributes) then
+        begin
+          if (Sender = ForeGroundUseDefaultCheckBox) then
+          begin
+            TSynAttributes(AttrToEdit).ParentForeground:= False;
+          end
+          else if (Sender = BackGroundUseDefaultCheckBox) then
+          begin
+            TSynAttributes(AttrToEdit).ParentBackground:= False;
+          end;
+        end;
       end
       end
       else begin
       else begin
         TheColorBox.Tag := TheColorBox.Selected;
         TheColorBox.Tag := TheColorBox.Selected;
-        TheColorBox.Selected := clDefault;
+        if not (AttrToEdit is TSynAttributes) then
+          TheColorBox.Selected := clDefault
+        else if Assigned(ColorElementTree.Selected) and Assigned(ColorElementTree.Selected.Parent) then
+        begin
+          if (Sender = ForeGroundUseDefaultCheckBox) then
+          begin
+            TSynAttributes(AttrToEdit).ParentForeground:= True;
+            TheColorBox.Selected := TSynRange(ColorElementTree.Selected.Parent.Data).Attribs.Foreground
+          end
+          else if (Sender = BackGroundUseDefaultCheckBox) then
+          begin
+            TSynAttributes(AttrToEdit).ParentBackground:= True;
+            TheColorBox.Selected := TSynRange(ColorElementTree.Selected.Parent.Data).Attribs.Background;
+          end;
+        end;
       end;
       end;
 
 
       if (Sender = ForeGroundUseDefaultCheckBox) and
       if (Sender = ForeGroundUseDefaultCheckBox) and
@@ -761,9 +831,46 @@ end;
 
 
 procedure TfrmOptionsEditorColors.UpdateCurrentScheme;
 procedure TfrmOptionsEditorColors.UpdateCurrentScheme;
 begin
 begin
+  ColorPreview.Invalidate;
   ColorElementTree.Invalidate;
   ColorElementTree.Invalidate;
 end;
 end;
 
 
+function TfrmOptionsEditorColors.TreeAddSet(Node: TTreeNode; SymbSet: TSynSet
+  ): TTreeNode;
+begin
+  Result:= ColorElementTree.Items.AddChild(Node, SymbSet.Name);
+  Result.Data:= SymbSet;
+end;
+
+function TfrmOptionsEditorColors.TreeAddRange(Node: TTreeNode; Range: TSynRange
+  ): TTreeNode;
+var
+  Index: Integer;
+begin
+  if (Node = nil) then
+    Result:= ColorElementTree.Items.Add(nil, Range.Name)
+  else begin
+    Result:= ColorElementTree.Items.AddChild(Node, Range.Name);
+  end;
+  Result.Data:= Range;
+
+  for Index := 0 to Range.SetCount - 1 do
+    TreeAddSet(Result, Range.Sets[Index]);
+
+  for Index := 0 to Range.RangeCount - 1 do
+    TreeAddRange(Result, Range.Ranges[Index]);
+
+  for Index := 0 to Range.KeyListCount - 1 do
+    TreeAddKeyList(Result, Range.KeyLists[Index]);
+end;
+
+function TfrmOptionsEditorColors.TreeAddKeyList(Node: TTreeNode;
+  KeyList: TSynKeyList): TTreeNode;
+begin
+  Result:= ColorElementTree.Items.AddChild(Node, KeyList.Name);
+  Result.Data:= KeyList;
+end;
+
 procedure TfrmOptionsEditorColors.Init;
 procedure TfrmOptionsEditorColors.Init;
 begin
 begin
   inherited Init;
   inherited Init;
@@ -778,16 +885,9 @@ begin
 end;
 end;
 
 
 procedure TfrmOptionsEditorColors.Load;
 procedure TfrmOptionsEditorColors.Load;
-var
-  Index: Integer;
 begin
 begin
   FHighl.Assign(dmHighl);
   FHighl.Assign(dmHighl);
   cmbLanguage.Items.Assign(FHighl.SynHighlighterList);
   cmbLanguage.Items.Assign(FHighl.SynHighlighterList);
-  for Index:= cmbLanguage.Items.Count - 1 downto 0 do
-  begin
-    if cmbLanguage.Items.Objects[Index] is TSynUniSyn then
-      cmbLanguage.Items.Delete(Index);
-  end;
   cmbLanguage.ItemIndex:= 0;
   cmbLanguage.ItemIndex:= 0;
   cmbLanguageChange(nil);
   cmbLanguageChange(nil);
 end;
 end;