Skip to content

Commit 8a08e77

Browse files
committed
feat: auto-switch to dark or light SQL colors in sync with the app's dark mode
1 parent 3f9e867 commit 8a08e77

File tree

5 files changed

+146
-126
lines changed

5 files changed

+146
-126
lines changed

heidisql.lpr

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
SysUtils, Dialogs,
1111
Forms, printer4lazarus, datetimectrls, LCLTranslator, Translations,
1212
{ you can add units after this }
13-
main, apphelpers, dbconnection;
13+
main, apphelpers, dbconnection, generic_types;
1414

1515
{$R *.res}
1616

@@ -67,11 +67,12 @@
6767

6868
WasDarkMode := AppSettings.ReadBool(asCurrentThemeIsDark);
6969
if (not WasDarkMode) and IsDarkModeEnabled then begin
70-
// todo: switch synedit colors and grid colors after current dark mode has changed
71-
// probably store a CurrentThemeIsDark=True/False in settings, then check here if that now changes and flip colors if so?
70+
// switch synedit colors and grid colors after current dark mode has changed
71+
SQLSynSchemes.ApplyScheme(SQLSynSchemes.SDarkScheme);
7272
end
7373
else if WasDarkMode and (not IsDarkModeEnabled) then begin
7474
// dito
75+
SQLSynSchemes.ApplyScheme(SQLSynSchemes.SLightScheme);
7576
end;
7677
AppSettings.WriteBool(asCurrentThemeIsDark, IsDarkModeEnabled);
7778
{$ENDIF}

source/generic_types.pas

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
interface
66

7-
uses fpjson, jsonparser, SysUtils, RegExpr;
7+
uses fpjson, jsonparser, SysUtils, RegExpr, SynEditHighlighter, SynHighlighterSQL,
8+
Generics.Collections, Graphics;
89

910
type
1011
TThreeStateBoolean = (nbUnset, nbFalse, nbTrue);
@@ -20,6 +21,19 @@ TRegExprUmlauts = class(TRegExpr)
2021
constructor Create;
2122
end;
2223

24+
// Light and dark Color schemes for SynEdit SQL highlighter
25+
TSynSQLSynList = specialize TObjectList<TSynSQLSyn>;
26+
TSynSQLSynSchemes = class(TSynSQLSynList)
27+
public
28+
const SDarkScheme = 'Dark';
29+
const SLightScheme = 'Light';
30+
const SBlackScheme = 'Black';
31+
const SWhiteScheme = 'White';
32+
constructor Create(AOwnsObjects: Boolean = True); reintroduce; overload;
33+
procedure ApplyScheme(Scheme: TSynSQLSyn); overload;
34+
procedure ApplyScheme(SchemeName: String); overload;
35+
end;
36+
2337
TFileExtImageIndex = record
2438
Ext: String;
2539
ImageIndex: Integer;
@@ -47,9 +61,13 @@ TFileExtImageIndex = record
4761
(Ext: 'sqlite3'; ImageIndex: 196)
4862
);
4963

64+
var
65+
SQLSynSchemes: TSynSQLSynSchemes;
5066

5167
implementation
5268

69+
uses apphelpers;
70+
5371
function GetFileExtImageIndex(Ext: String): Integer;
5472
var
5573
i: Integer;
@@ -91,8 +109,109 @@ constructor TRegExprUmlauts.Create;
91109
WordChars := WordChars + 'äÄöÖüÜÿŸáÁéÉíÍóÓúÚýÝćĆńŃŕŔśŚźŹĺĹàÀèÈìÌòÒùÙâÂêÊîÎôÔûÛãÃõÕñÑçÇşŞţŢåÅæÆœŒøØß';
92110
end;
93111

112+
{ TSynSQLSynSchemes }
113+
114+
constructor TSynSQLSynSchemes.Create(AOwnsObjects: Boolean = True);
115+
var
116+
Scheme: TSynSQLSyn;
117+
begin
118+
inherited Create(AOwnsObjects);
119+
120+
Scheme := TSynSQLSyn.Create(nil);
121+
Scheme.Name := SDarkScheme;
122+
Scheme.SQLDialect := sqlMySQL;
123+
Scheme.CommentAttri.Foreground := 8710076;
124+
Scheme.DataTypeAttri.Foreground := 11184895;
125+
Scheme.FunctionAttri.Foreground := 15792639;
126+
Scheme.IdentifierAttri.Foreground := 6460927;
127+
Scheme.KeyAttri.Foreground := 15792639;
128+
Scheme.NumberAttri.Foreground := 4610525;
129+
Scheme.StringAttri.Foreground := 5293907;
130+
Scheme.SymbolAttri.Foreground := 15792639;
131+
Scheme.TableNameAttri.Foreground := 16755327;
132+
Scheme.VariableAttri.Foreground := clPurple;
133+
Add(Scheme);
134+
135+
Scheme := TSynSQLSyn.Create(nil);
136+
Scheme.Name := SLightScheme;
137+
Scheme.SQLDialect := sqlMySQL;
138+
Scheme.CommentAttri.Foreground := clGray;
139+
Scheme.DataTypeAttri.Foreground := clMaroon;
140+
Scheme.FunctionAttri.Foreground := clNavy;
141+
Scheme.IdentifierAttri.Foreground := clOlive;
142+
Scheme.KeyAttri.Foreground := clBlue;
143+
Scheme.NumberAttri.Foreground := clPurple;
144+
Scheme.StringAttri.Foreground := clGreen;
145+
Scheme.SymbolAttri.Foreground := clBlue;
146+
Scheme.TableNameAttri.Foreground := clFuchsia;
147+
Scheme.VariableAttri.Foreground := clPurple;
148+
Add(Scheme);
149+
150+
Scheme := TSynSQLSyn.Create(nil);
151+
Scheme.Name := SBlackScheme;
152+
Scheme.SQLDialect := sqlMySQL;
153+
Scheme.CommentAttri.Foreground := clBlack;
154+
Scheme.DataTypeAttri.Foreground := clBlack;
155+
Scheme.FunctionAttri.Foreground := clBlack;
156+
Scheme.IdentifierAttri.Foreground := clBlack;
157+
Scheme.KeyAttri.Foreground := clBlack;
158+
Scheme.NumberAttri.Foreground := clBlack;
159+
Scheme.StringAttri.Foreground := clBlack;
160+
Scheme.SymbolAttri.Foreground := clBlack;
161+
Scheme.TableNameAttri.Foreground := clBlack;
162+
Scheme.VariableAttri.Foreground := clBlack;
163+
Add(Scheme);
164+
165+
Scheme := TSynSQLSyn.Create(nil);
166+
Scheme.Name := SWhiteScheme;
167+
Scheme.SQLDialect := sqlMySQL;
168+
Scheme.CommentAttri.Foreground := clWhite;
169+
Scheme.DataTypeAttri.Foreground := clWhite;
170+
Scheme.FunctionAttri.Foreground := clWhite;
171+
Scheme.IdentifierAttri.Foreground := clWhite;
172+
Scheme.KeyAttri.Foreground := clWhite;
173+
Scheme.NumberAttri.Foreground := clWhite;
174+
Scheme.StringAttri.Foreground := clWhite;
175+
Scheme.SymbolAttri.Foreground := clWhite;
176+
Scheme.TableNameAttri.Foreground := clWhite;
177+
Scheme.VariableAttri.Foreground := clWhite;
178+
Add(Scheme);
179+
end;
180+
181+
procedure TSynSQLSynSchemes.ApplyScheme(Scheme: TSynSQLSyn);
182+
var
183+
i: Integer;
184+
Attri: TSynHighlighterAttributes;
185+
begin
186+
for i:=0 to Scheme.AttrCount - 1 do begin
187+
Attri := Scheme.Attribute[i];
188+
AppSettings.WriteInt(asHighlighterForeground, Attri.Foreground, Attri.Name);
189+
AppSettings.WriteInt(asHighlighterBackground, Attri.Background, Attri.Name);
190+
AppSettings.WriteInt(asHighlighterStyle, Attri.IntegerStyle, Attri.Name);
191+
end;
192+
end;
193+
194+
procedure TSynSQLSynSchemes.ApplyScheme(SchemeName: String);
195+
var
196+
Scheme: TSynSQLSyn;
197+
Found: Boolean;
198+
begin
199+
Found := False;
200+
for Scheme in Self do begin
201+
if Scheme.Name = SchemeName then begin
202+
ApplyScheme(Scheme);
203+
Found := True;
204+
Break;
205+
end;
206+
end;
207+
if not Found then
208+
raise Exception.Create('SQL scheme not found: '+SchemeName);
209+
end;
210+
94211
initialization
95212

96213
SetJSONInstanceType(jitNumberFloat, TJSONFloatNumberUntouched);
97214

215+
SQLSynSchemes := TSynSQLSynSchemes.Create(True);
216+
98217
end.

source/preferences.lfm

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -2049,72 +2049,4 @@ object frmPreferences: TfrmPreferences
20492049
Left = 730
20502050
Top = 490
20512051
end
2052-
object SynSQLSyn_Dark: TSynSQLSyn
2053-
DefaultFilter = 'SQL Files (*.sql)|*.sql'
2054-
Enabled = False
2055-
CommentAttri.Foreground = 8710076
2056-
DataTypeAttri.Foreground = 11184895
2057-
FunctionAttri.Foreground = 15792639
2058-
IdentifierAttri.Foreground = 6460927
2059-
KeyAttri.Foreground = 15792639
2060-
NumberAttri.Foreground = 4610525
2061-
StringAttri.Foreground = 5293907
2062-
SymbolAttri.Foreground = 15792639
2063-
TableNameAttri.Foreground = 16755327
2064-
VariableAttri.Foreground = clPurple
2065-
SQLDialect = sqlMySQL
2066-
Left = 740
2067-
Top = 210
2068-
end
2069-
object SynSQLSyn_Light: TSynSQLSyn
2070-
DefaultFilter = 'SQL Files (*.sql)|*.sql'
2071-
Enabled = False
2072-
CommentAttri.Foreground = clGray
2073-
DataTypeAttri.Foreground = clMaroon
2074-
FunctionAttri.Foreground = clNavy
2075-
IdentifierAttri.Foreground = clOlive
2076-
KeyAttri.Foreground = clBlue
2077-
NumberAttri.Foreground = clPurple
2078-
StringAttri.Foreground = clGreen
2079-
SymbolAttri.Foreground = clBlue
2080-
TableNameAttri.Foreground = clFuchsia
2081-
VariableAttri.Foreground = clPurple
2082-
SQLDialect = sqlMySQL
2083-
Left = 740
2084-
Top = 140
2085-
end
2086-
object SynSQLSyn_Black: TSynSQLSyn
2087-
DefaultFilter = 'SQL Files (*.sql)|*.sql'
2088-
Enabled = False
2089-
CommentAttri.Foreground = clBlack
2090-
DataTypeAttri.Foreground = clBlack
2091-
FunctionAttri.Foreground = clBlack
2092-
IdentifierAttri.Foreground = clBlack
2093-
KeyAttri.Foreground = clBlack
2094-
NumberAttri.Foreground = clBlack
2095-
StringAttri.Foreground = clBlack
2096-
SymbolAttri.Foreground = clBlack
2097-
TableNameAttri.Foreground = clBlack
2098-
VariableAttri.Foreground = clBlack
2099-
SQLDialect = sqlMySQL
2100-
Left = 735
2101-
Top = 285
2102-
end
2103-
object SynSQLSyn_White: TSynSQLSyn
2104-
DefaultFilter = 'SQL Files (*.sql)|*.sql'
2105-
Enabled = False
2106-
CommentAttri.Foreground = clWhite
2107-
DataTypeAttri.Foreground = clWhite
2108-
FunctionAttri.Foreground = clWhite
2109-
IdentifierAttri.Foreground = clWhite
2110-
KeyAttri.Foreground = clWhite
2111-
NumberAttri.Foreground = clWhite
2112-
StringAttri.Foreground = clWhite
2113-
SymbolAttri.Foreground = clWhite
2114-
TableNameAttri.Foreground = clWhite
2115-
VariableAttri.Foreground = clWhite
2116-
SQLDialect = sqlMySQL
2117-
Left = 735
2118-
Top = 355
2119-
end
21202052
end

source/preferences.pas

Lines changed: 21 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,6 @@ TfrmPreferences = class(TExtForm)
154154
comboTheme: TComboBox;
155155
lblEditorColorsPreset: TLabel;
156156
comboEditorColorsPreset: TComboBox;
157-
SynSQLSyn_Dark: TSynSQLSyn;
158-
SynSQLSyn_Light: TSynSQLSyn;
159-
SynSQLSyn_Black: TSynSQLSyn;
160-
SynSQLSyn_White: TSynSQLSyn;
161157
comboGridTextColorsPreset: TComboBox;
162158
lblIconPack: TLabel;
163159
comboIconPack: TComboBox;
@@ -259,7 +255,7 @@ TfrmPreferences = class(TExtForm)
259255

260256
implementation
261257

262-
uses main, apphelpers, extfiledialog;
258+
uses main, apphelpers, extfiledialog, generic_types;
263259

264260
{$R *.lfm}
265261

@@ -297,8 +293,6 @@ procedure TfrmPreferences.pagecontrolMainChange(Sender: TObject);
297293
}
298294
procedure TfrmPreferences.Apply(Sender: TObject);
299295
var
300-
i: Integer;
301-
Attri: TSynHighlighterAttributes;
302296
CatNode, ItemNode: PVirtualNode;
303297
Data: PShortcutItemData;
304298
LangCode: String;
@@ -325,12 +319,7 @@ procedure TfrmPreferences.Apply(Sender: TObject);
325319
AppSettings.WriteInt(asQueryHistoryKeepDays, MakeInt(editQueryHistoryKeepDays.Text));
326320
AppSettings.WriteBool(asLogHorizontalScrollbar, chkHorizontalScrollbar.Checked);
327321
AppSettings.WriteBool(asLogTimestamp, chkLogTimestamp.Checked);
328-
for i:=0 to SynSQLSynSQLSample.AttrCount - 1 do begin
329-
Attri := SynSQLSynSQLSample.Attribute[i];
330-
AppSettings.WriteInt(asHighlighterForeground, Attri.Foreground, Attri.Name);
331-
AppSettings.WriteInt(asHighlighterBackground, Attri.Background, Attri.Name);
332-
AppSettings.WriteInt(asHighlighterStyle, Attri.IntegerStyle, Attri.Name);
333-
end;
322+
SQLSynSchemes.ApplyScheme(SynSQLSynSQLSample);
334323
AppSettings.WriteString(asSQLColActiveLine, ColorToString(SynMemoSQLSample.LineHighlightColor.Background));
335324
AppSettings.WriteString(asSQLColMatchingBraceForeground, ColorToString(MainForm.MatchingBraceForegroundColor));
336325
AppSettings.WriteString(asSQLColMatchingBraceBackground, ColorToString(MainForm.MatchingBraceBackgroundColor));
@@ -537,7 +526,6 @@ procedure TfrmPreferences.FormCreate(Sender: TObject);
537526
dtc: TDBDatatypeCategoryIndex;
538527
//Styles: TArray<String>;
539528
Highlighter: TSynSQLSyn;
540-
Name: String;
541529
GridColorsPreset: TGridColorsPreset;
542530
IconPack: String;
543531
Reformatter: TfrmReformatter;
@@ -605,17 +593,8 @@ procedure TfrmPreferences.FormCreate(Sender: TObject);
605593
comboSQLColElement.Items.Add(_('Brace matching color'));
606594
comboSQLColElement.ItemIndex := 0;
607595
// Enumerate highlighter presets
608-
for i:=0 to ComponentCount-1 do begin
609-
if (Components[i] is TSynSQLSyn)
610-
and (Components[i] <> SynMemoSQLSample.Highlighter)
611-
then begin
612-
Highlighter := Components[i] as TSynSQLSyn;
613-
Name := Highlighter.Name;
614-
Name := RegExprGetMatch('_([^_]+)$', Name, 1);
615-
if Name <> '' then begin
616-
comboEditorColorsPreset.Items.Add(_(Name));
617-
end;
618-
end;
596+
for Highlighter in SQLSynSchemes do begin
597+
comboEditorColorsPreset.Items.Add(_(Highlighter.Name));
619598
end;
620599

621600
// Grid formatting
@@ -970,40 +949,29 @@ procedure TfrmPreferences.comboEditorColorsPresetChange(Sender: TObject);
970949
i, j: Integer;
971950
Highlighter: TSynSQLSyn;
972951
FoundHighlighter: Boolean;
973-
rx: TRegExpr;
974952
TranslatedHighlighterName: String;
975953
begin
976954
// Color preset selected
977955
FoundHighlighter := False;
978-
rx := TRegExpr.Create;
979-
rx.Expression := '.+_([a-zA-Z0-9]+)$';
980-
for i:=0 to ComponentCount-1 do begin
981-
if (Components[i] is TSynSQLSyn) and (Components[i] <> SynMemoSQLSample.Highlighter) then begin
982-
Highlighter := Components[i] as TSynSQLSyn;
983-
984-
// Translate highlighter postfix after last underscore: SynSQLSyn_White, SynSQLSyn_Black, ...
985-
TranslatedHighlighterName := '';
986-
if rx.Exec(Highlighter.Name) then begin
987-
TranslatedHighlighterName := _(rx.Match[1]);
956+
for Highlighter in SQLSynSchemes do begin
957+
TranslatedHighlighterName := _(Highlighter.Name);
958+
// ... so we can compare that with the selected dropdown text
959+
if TranslatedHighlighterName = comboEditorColorsPreset.Text then begin
960+
FoundHighlighter := True;
961+
for j:=0 to SynSQLSynSQLSample.AttrCount - 1 do begin
962+
SynSQLSynSQLSample.Attribute[j].AssignColorAndStyle(Highlighter.Attribute[j]);
988963
end;
989-
// ... so we can compare that with the selected dropdown text
990-
if TranslatedHighlighterName = comboEditorColorsPreset.Text then begin
991-
FoundHighlighter := True;
992-
for j:=0 to SynSQLSynSQLSample.AttrCount - 1 do begin
993-
SynSQLSynSQLSample.Attribute[j].AssignColorAndStyle(Highlighter.Attribute[j]);
994-
end;
995-
// Use 3 hardcoded default values for additional colors, which are not part
996-
// of the highlighter's attributes
997-
SynMemoSQLSample.LineHighlightColor.Background := StringToColor(AppSettings.GetDefaultString(asSQLColActiveLine));
998-
if IsDarkModeEnabled then begin // This is yet wrong, and should be based on the selected but not yet saved theme setting
999-
MainForm.MatchingBraceForegroundColor := $0028EFFF;
1000-
MainForm.MatchingBraceBackgroundColor := $004D513B;
1001-
end else begin
1002-
MainForm.MatchingBraceForegroundColor := StringToColor(AppSettings.GetDefaultString(asSQLColMatchingBraceForeground));
1003-
MainForm.MatchingBraceBackgroundColor := StringToColor(AppSettings.GetDefaultString(asSQLColMatchingBraceBackground));
1004-
end;
1005-
Break;
964+
// Use 3 hardcoded default values for additional colors, which are not part
965+
// of the highlighter's attributes
966+
SynMemoSQLSample.LineHighlightColor.Background := StringToColor(AppSettings.GetDefaultString(asSQLColActiveLine));
967+
if IsDarkModeEnabled then begin // This is yet wrong, and should be based on the selected but not yet saved theme setting
968+
MainForm.MatchingBraceForegroundColor := $0028EFFF;
969+
MainForm.MatchingBraceBackgroundColor := $004D513B;
970+
end else begin
971+
MainForm.MatchingBraceForegroundColor := StringToColor(AppSettings.GetDefaultString(asSQLColMatchingBraceForeground));
972+
MainForm.MatchingBraceBackgroundColor := StringToColor(AppSettings.GetDefaultString(asSQLColMatchingBraceBackground));
1006973
end;
974+
Break;
1007975
end;
1008976
end;
1009977
if not FoundHighlighter then begin

source/texteditor.pas

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ interface
1010
apphelpers, ActnList, extra_controls,
1111
ExtCtrls, dbconnection, SynEdit, SynEditHighlighter, customize_highlighter,
1212
Laz2_DOM, Laz2_XMLRead, Laz2_XMLWrite,
13-
reformatter, jsonparser, extfiledialog, generic_types, lazaruscompat,
13+
reformatter, jsonparser, extfiledialog, lazaruscompat,
1414

1515
SynHighlighterBat,
1616
SynHighlighterCpp, SynHighlighterCss,

0 commit comments

Comments
 (0)