1 { PropertyEditor
2
3 Copyright (C) <year> <name of author> <contact>
4
5 This library is free software; you can redistribute it and/or modify it
6 under the terms of the GNU Library General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or (at your
8 option) any later version.
9
10 This program is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
13 for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA.
18 }
19 unit SynPropertyEditObjectList;
20
21 {$mode objfpc}{$H+}
22
23 interface
24
25 uses
26 Classes, SysUtils, LCLProc,
27 SynEdit, SynGutterBase, SynEditMiscClasses, SynEditMouseCmds, SynEditKeyCmds,
28 SynDesignStringConstants,
29 PropEdits, PropEditUtils, Forms, StdCtrls, ComCtrls, Dialogs, ComponentEditors,
30 ObjInspStrConsts, Controls, IDEImagesIntf, typinfo, FormEditingIntf, SynEditTypes;
31
32 type
33
34 { TSynEdOptionsPropertyEditor }
35
36 TSynEdOptionsPropertyEditor = class(TSetPropertyEditor)
37 public
38 procedure GetProperties(Proc: TGetPropEditProc); override;
39 end;
40
41 { TSynPropertEditClassList }
42
43 TSynPropertyEditObjectList = class(TListPropertyEditor)
44 protected
ReadElementCountnull45 function ReadElementCount: integer; override;
ReadElementnull46 function ReadElement(Index: integer): TPersistent; override;
ClassListnull47 class function ClassList: TStringList; virtual; abstract;
48 public
GetAttributesnull49 function GetAttributes: TPropertyAttributes; override;
50 procedure Edit; override;
ShowClassListEditornull51 class function ShowClassListEditor(AClassList: TSynObjectList;
52 OwnerPersistent: TPersistent; const PropName: String): TCustomForm;
53 end;
54
55 { TSynPropertyEditGutterPartList }
56
57 TSynPropertyEditGutterPartList = class(TSynPropertyEditObjectList)
58 protected
ClassListnull59 class function ClassList: TStringList; override;
60 end;
61
62 { TSynObjectPartListPropertyEditorForm }
63
64 TSynObjectPartListPropertyEditorForm = class(TForm)
65 SynObjectPartsListBox: TListBox;
66 ToolBar1: TToolBar;
67 AddButton: TToolButton;
68 ClassComboBox: TComboBox;
69 DeleteButton: TToolButton;
70 ToolButton3: TToolButton;
71 MoveUpButton: TToolButton;
72 MoveDownButton: TToolButton;
73 procedure AddButtonClick(Sender: TObject);
74 procedure SynObjectPartsListBoxClick(Sender: TObject);
75 procedure DeleteButtonClick(Sender: TObject);
76 procedure FormCreate(Sender: TObject);
77 procedure FormDestroy(Sender: TObject);
78 procedure MoveDownButtonClick(Sender: TObject);
79 procedure MoveUpButtonClick(Sender: TObject);
80 private
81 FSynObjectPartList: TSynObjectList;
82 FOwnerPersistent: TPersistent;
83 FPropertyName: String;
84 FClassesList: TStringList;
85 protected
86 procedure UpdateCaption;
87 procedure UpdateButtons;
88 procedure ComponentRenamed(AComponent: TComponent);
89 procedure PersistentDeleting(APersistent: TPersistent);
90 procedure RefreshPropertyValues;
91 public
92 procedure FillSynObjectPartsListBox;
93 procedure SelectInObjectInspector(UnselectAll: Boolean);
94 procedure SetSynObjectPartList(NewSynObjectPartList: TSynObjectList;
95 NewClassesList: TStringList;
96 NewOwnerPersistent: TPersistent; const NewPropName: String);
97 procedure Modified;
98 public
99 property SynObjectPartList: TSynObjectList read FSynObjectPartList;
100 property OwnerPersistent: TPersistent read FOwnerPersistent;
101 property PropertyName: String read FPropertyName;
102 end;
103
104 { TSynKeyCommandPropertyEditor }
105
106 TSynKeyCommandPropertyEditor = class(TIntegerPropertyEditor)
107 public
GetAttributesnull108 function GetAttributes: TPropertyAttributes; override;
OrdValueToVisualValuenull109 function OrdValueToVisualValue(OrdValue: longint): string; override;
110 procedure GetValues(Proc: TGetStrProc); override;
111 procedure SetValue(const NewValue: ansistring); override;
112 end;
113
114 { TSynMouseCommandPropertyEditor }
115
116 TSynMouseCommandPropertyEditor = class(TIntegerPropertyEditor)
117 public
GetAttributesnull118 function GetAttributes: TPropertyAttributes; override;
OrdValueToVisualValuenull119 function OrdValueToVisualValue(OrdValue: longint): string; override;
120 procedure GetValues(Proc: TGetStrProc); override;
121 procedure SetValue(const NewValue: ansistring); override;
122 end;
123
124 { TSynEditComponentEditor }
125
126 TSynEditComponentEditor = class(TDefaultComponentEditor)
127 public
GetVerbCountnull128 function GetVerbCount: Integer; override;
GetVerbnull129 function GetVerb(Index: Integer): string; override;
130 procedure ExecuteVerb(Index: Integer); override;
131 end;
132
133 procedure RegisterGutterPartClass(AClass: TSynGutterPartBaseClass; AName: String);
134
135 implementation
136
137 {$R *.lfm}
138
139 const
140 SynObjectPartListForm: TSynObjectPartListPropertyEditorForm = nil;
141 KnownSynGutterPartClasses: TStringList = nil;
142
143 procedure RegisterGutterPartClass(AClass: TSynGutterPartBaseClass; AName: String);
144 begin
145 if KnownSynGutterPartClasses = nil then
146 KnownSynGutterPartClasses := TStringList.Create;
147 KnownSynGutterPartClasses.AddObject(AName, TObject(Pointer(AClass)));
148 end;
149
150 { TSynEditComponentEditor }
151
GetVerbCountnull152 function TSynEditComponentEditor.GetVerbCount: Integer;
153 begin
154 Result := inherited GetVerbCount;
155 Result := Result + 1;
156 end;
157
TSynEditComponentEditor.GetVerbnull158 function TSynEditComponentEditor.GetVerb(Index: Integer): string;
159 begin
160 case Index - (inherited GetVerbCount) of
161 0: Result := syndsResetMouseActions;
162 else
163 Result := inherited GetVerb(Index);
164 end;
165 end;
166
167 procedure TSynEditComponentEditor.ExecuteVerb(Index: Integer);
168 var
169 Hook: TPropertyEditorHook;
170 begin
171 case Index - (inherited GetVerbCount) of
172 0: begin
173 if Component is TCustomSynEdit then
174 TCustomSynEdit(Component).ResetMouseActions;
175 Modified;
176 GetHook(Hook);
177 if Assigned(Hook) then Hook.Modified(Self);
178 end;
179 else
180 inherited ExecuteVerb(Index);
181 end;
182 end;
183
184 { TSynEdOptionsPropertyEditor }
185
186 procedure TSynEdOptionsPropertyEditor.GetProperties(Proc: TGetPropEditProc);
187 var
188 I: Integer;
189 begin
190 with GetTypeData(GetTypeData(GetPropType)^.CompType)^ do
191 for I := MinValue to MaxValue do
192 if not(TSynEditorOption(I) in SYNEDIT_UNIMPLEMENTED_OPTIONS)
193 then
194 Proc(TSetElementPropertyEditor.Create(Self, I));
195 end;
196
197 { TSynKeyCommandPropertyEditor }
198
GetAttributesnull199 function TSynKeyCommandPropertyEditor.GetAttributes: TPropertyAttributes;
200 begin
201 Result := [paMultiSelect, paValueList, paRevertable];
202 end;
203
OrdValueToVisualValuenull204 function TSynKeyCommandPropertyEditor.OrdValueToVisualValue(OrdValue: longint): string;
205 begin
206 Result:='';
207 if not EditorCommandToIdent(OrdValue, Result) then
208 Result := inherited OrdValueToVisualValue(OrdValue);
209 end;
210
211 procedure TSynKeyCommandPropertyEditor.GetValues(Proc: TGetStrProc);
212 var
213 CValue: Integer;
214 begin
215 CValue:=0;
216 if not IdentToSynMouseCmd(GetVisualValue, CValue) then Proc(GetVisualValue);
217 GetEditorCommandValues(Proc);
218 end;
219
220 procedure TSynKeyCommandPropertyEditor.SetValue(const NewValue: ansistring);
221 var
222 CValue: Integer;
223 begin
224 CValue:=0;
225 if IdentToEditorCommand(NewValue, CValue) then SetOrdValue(CValue)
226 else inherited SetValue(NewValue);
227 end;
228
229 { TSynMouseCommandPropertyEditor }
230
GetAttributesnull231 function TSynMouseCommandPropertyEditor.GetAttributes: TPropertyAttributes;
232 begin
233 Result := [paMultiSelect, paValueList, paRevertable];
234 end;
235
OrdValueToVisualValuenull236 function TSynMouseCommandPropertyEditor.OrdValueToVisualValue(OrdValue: longint): string;
237 begin
238 Result:='';
239 if not SynMouseCmdToIdent(OrdValue, Result) then
240 Result := inherited OrdValueToVisualValue(OrdValue);
241 end;
242
243 procedure TSynMouseCommandPropertyEditor.GetValues(Proc: TGetStrProc);
244 var
245 CValue: Integer;
246 CName: String;
247 i: TSynEditorMouseCommand;
248 begin
249 CValue:=0;
250 CName:='';
251 if not IdentToSynMouseCmd(GetVisualValue, CValue) then Proc(GetVisualValue);
252 for i := 0 to emcMax do
253 if SynMouseCmdToIdent(i, CName) then Proc(CName);
254 end;
255
256 procedure TSynMouseCommandPropertyEditor.SetValue(const NewValue: ansistring);
257 var
258 CValue: Integer;
259 begin
260 CValue:=0;
261 if IdentToSynMouseCmd(NewValue, CValue) then SetOrdValue(CValue)
262 else inherited SetValue(NewValue);
263 end;
264
265 { TSynObjectPartListPropertyEditorForm }
266
267 procedure TSynObjectPartListPropertyEditorForm.AddButtonClick(Sender: TObject);
268 var
269 i: Integer;
270 NewPart: TSynObjectListItem;
271 begin
272 if (SynObjectPartList = nil) or (FClassesList = nil) then Exit;
273
274 i := ClassComboBox.ItemIndex;
275 if (i < 0) or (i >= FClassesList.Count) then
276 exit;
277 NewPart := TSynObjectListItemClass(Pointer(FClassesList.Objects[i])).Create(SynObjectPartList);
278 NewPart.Name := FormEditingHook.CreateUniqueComponentName(NewPart.ClassName, SynObjectPartList);
279
280 FillSynObjectPartsListBox;
281 if SynObjectPartsListBox.Items.Count > 0 then
282 SynObjectPartsListBox.ItemIndex := SynObjectPartsListBox.Items.Count - 1;
283 SelectInObjectInspector(False);
284 UpdateButtons;
285 UpdateCaption;
286 Modified;
287 end;
288
289 procedure TSynObjectPartListPropertyEditorForm.SynObjectPartsListBoxClick(Sender: TObject);
290 begin
291 UpdateButtons;
292 UpdateCaption;
293 SelectInObjectInspector(False);
294 end;
295
296 procedure TSynObjectPartListPropertyEditorForm.DeleteButtonClick(Sender: TObject);
297 var
298 I : Integer;
299 NewItemIndex: Integer;
300 begin
301 if SynObjectPartList = nil then Exit;
302
303 I := SynObjectPartsListBox.ItemIndex;
304 if (I >= 0) and (I < SynObjectPartList.Count) then
305 begin
306 if MessageDlg(oisConfirmDelete,
307 Format(oisDeleteItem, [SynObjectPartList.BaseItems[I].DisplayName]),
308 mtConfirmation, [mbYes, mbNo], 0) = mrYes then
309 begin
310 // select other item, or unselect
311 NewItemIndex := I + 1;
312 while (NewItemIndex < SynObjectPartsListBox.Items.Count)
313 and (SynObjectPartsListBox.Selected[NewItemIndex]) do Inc(NewItemIndex);
314
315 if NewItemIndex = SynObjectPartsListBox.Items.Count then
316 begin
317 NewItemIndex := 0;
318 while (NewItemIndex < Pred(I))
319 and not (SynObjectPartsListBox.Selected[NewItemIndex]) do Inc(NewItemIndex);
320
321 if NewItemIndex = I then NewItemIndex := -1;
322 end;
323
324 SynObjectPartsListBox.ItemIndex := -1;
325
326 if NewItemIndex > I then Dec(NewItemIndex);
327 // unselect all items in OI
328 SelectInObjectInspector(True);
329 // now delete
330 SynObjectPartList.BaseItems[I].Free;
331 // update listbox after whatever happened
332 FillSynObjectPartsListBox;
333 // set NewItemIndex
334 if NewItemIndex < SynObjectPartsListBox.Items.Count then
335 begin
336 SynObjectPartsListBox.ItemIndex := NewItemIndex;
337 SelectInObjectInspector(False);
338 end;
339 Modified;
340 end;
341 end;
342 UpdateButtons;
343 UpdateCaption;
344 end;
345
346 procedure TSynObjectPartListPropertyEditorForm.FormCreate(Sender: TObject);
347 begin
348 ToolBar1.Images := IDEImages.Images_16;
349 AddButton.Caption := oiColEditAdd;
350 DeleteButton.Caption := oiColEditDelete;
351 MoveUpButton.Caption := oiColEditUp;
352 MoveDownButton.Caption := oiColEditDown;
353 AddButton.ImageIndex := IDEImages.LoadImage('laz_add');
354 DeleteButton.ImageIndex := IDEImages.LoadImage('laz_delete');
355 MoveUpButton.ImageIndex := IDEImages.LoadImage('arrow_up');
356 MoveDownButton.ImageIndex := IDEImages.LoadImage('arrow_down');
357 end;
358
359 procedure TSynObjectPartListPropertyEditorForm.FormDestroy(Sender: TObject);
360 begin
361 if GlobalDesignHook <> nil then
362 GlobalDesignHook.RemoveAllHandlersForObject(Self);
363 end;
364
365 procedure TSynObjectPartListPropertyEditorForm.MoveDownButtonClick(Sender: TObject);
366 var
367 I: Integer;
368 begin
369 if SynObjectPartList = nil then Exit;
370
371 I := SynObjectPartsListBox.ItemIndex;
372 if I >= SynObjectPartList.Count - 1 then Exit;
373
374 SynObjectPartList.BaseItems[I].Index := I + 1;
375 SynObjectPartsListBox.ItemIndex := I + 1;
376
377 FillSynObjectPartsListBox;
378 SelectInObjectInspector(False);
379 Modified;
380 end;
381
382 procedure TSynObjectPartListPropertyEditorForm.MoveUpButtonClick(Sender: TObject);
383 var
384 I: Integer;
385 begin
386 if SynObjectPartList = nil then Exit;
387
388 I := SynObjectPartsListBox.ItemIndex;
389 if I < 0 then Exit;
390
391 SynObjectPartList.BaseItems[I].Index := I - 1;
392 SynObjectPartsListBox.ItemIndex := I - 1;
393
394 FillSynObjectPartsListBox;
395 SelectInObjectInspector(False);
396 Modified;
397 end;
398
399 procedure TSynObjectPartListPropertyEditorForm.UpdateCaption;
400 var
401 NewCaption: String;
402 begin
403 //"Editing ComponentName.PropertyName[Index]"
404 if OwnerPersistent is TComponent then
405 NewCaption := TComponent(OwnerPersistent).Name
406 else
407 if OwnerPersistent <> nil then
408 NewCaption := OwnerPersistent.GetNamePath
409 else
410 NewCaption := '';
411
412 if NewCaption <> '' then NewCaption := NewCaption + '.';
413 NewCaption := oiColEditEditing + ' ' + NewCaption + PropertyName;
414
415 if SynObjectPartsListBox.ItemIndex > -1 then
416 NewCaption := NewCaption + '[' + IntToStr(SynObjectPartsListBox.ItemIndex) + ']';
417 Caption := NewCaption;
418 end;
419
420 procedure TSynObjectPartListPropertyEditorForm.UpdateButtons;
421 var
422 I: Integer;
423 begin
424 if SynObjectPartList = nil then begin
425 AddButton.Enabled := False;
426 DeleteButton.Enabled := False;
427 MoveUpButton.Enabled := False;
428 MoveDownButton.Enabled := False;
429 exit;
430 end;
431 I := SynObjectPartsListBox.ItemIndex;
432 AddButton.Enabled := True;
433 DeleteButton.Enabled := I > -1;
434 MoveUpButton.Enabled := I > 0;
435 MoveDownButton.Enabled := (I >= 0) and (I < SynObjectPartList.Count - 1);
436 end;
437
438 procedure TSynObjectPartListPropertyEditorForm.ComponentRenamed(AComponent: TComponent);
439 begin
440 if AComponent = OwnerPersistent then UpdateCaption;
441 end;
442
443 procedure TSynObjectPartListPropertyEditorForm.PersistentDeleting(APersistent: TPersistent);
444 var
445 OldSynObjectPartList: TSynObjectList;
446 I: Integer;
447 begin
448 debugln(['TSynObjectPartListPropertyEditorForm.PersistentDeleting ']);
449 if APersistent = OwnerPersistent then
450 begin
451 OldSynObjectPartList := SynObjectPartList;
452 SetSynObjectPartList(nil, nil, nil, '');
453 GlobalDesignHook.Unselect(OldSynObjectPartList);
454 for I := 0 to OldSynObjectPartList.Count - 1 do
455 GlobalDesignHook.Unselect(OldSynObjectPartList.BaseItems[I]);
456 if GlobalDesignHook.LookupRoot = OldSynObjectPartList then
457 GlobalDesignHook.LookupRoot := nil;
458 Hide;
459 end;
460 end;
461
462
463 procedure TSynObjectPartListPropertyEditorForm.RefreshPropertyValues;
464 begin
465 FillSynObjectPartsListBox;
466 Modified;
467 end;
468
469 procedure TSynObjectPartListPropertyEditorForm.FillSynObjectPartsListBox;
470 var
471 I: Integer;
472 CurItem: String;
473 Cnt: Integer;
474 begin
475 SynObjectPartsListBox.Items.BeginUpdate;
476 try
477 if SynObjectPartList <> nil then Cnt := SynObjectPartList.Count
478 else Cnt := 0;
479
480 // add or replace list items
481 for I := 0 to Cnt - 1 do
482 begin
483 CurItem := IntToStr(I) + ' - ' + SynObjectPartList.BaseItems[I].DisplayName;
484 if I >= SynObjectPartsListBox.Items.Count then
485 SynObjectPartsListBox.Items.Add(CurItem)
486 else
487 SynObjectPartsListBox.Items[I] := CurItem;
488 end;
489
490 // delete unneeded list items
491 if Cnt > 0 then
492 begin
493 while SynObjectPartsListBox.Items.Count > Cnt do
494 begin
495 SynObjectPartsListBox.Items.Delete(SynObjectPartsListBox.Items.Count - 1);
496 end;
497 end
498 else
499 begin
500 SynObjectPartsListBox.Items.Clear;
501 end;
502 finally
503 SynObjectPartsListBox.Items.EndUpdate;
504 UpdateButtons;
505 UpdateCaption;
506 end;
507 end;
508
509 procedure TSynObjectPartListPropertyEditorForm.SelectInObjectInspector(UnselectAll: Boolean);
510 var
511 I: Integer;
512 NewSelection: TPersistentSelectionList;
513 begin
514 if SynObjectPartList = nil then Exit;
515 // select in OI
516 NewSelection := TPersistentSelectionList.Create;
517 try
518 if not UnselectAll then
519 begin
520 for I := 0 to SynObjectPartsListBox.Items.Count - 1 do
521 if SynObjectPartsListBox.Selected[I] then
522 NewSelection.Add(SynObjectPartList.BaseItems[I]);
523 end;
524 GlobalDesignHook.SetSelection(NewSelection);
525 GlobalDesignHook.LookupRoot := GetLookupRootForComponent(OwnerPersistent);
526 finally
527 NewSelection.Free;
528 end;
529 end;
530
531 procedure TSynObjectPartListPropertyEditorForm.SetSynObjectPartList
532 (NewSynObjectPartList: TSynObjectList; NewClassesList: TStringList;
533 NewOwnerPersistent: TPersistent; const NewPropName: String);
534 begin
535 if (FSynObjectPartList = NewSynObjectPartList)
536 and (FClassesList = NewClassesList)
537 and (FOwnerPersistent = NewOwnerPersistent)
538 and (FPropertyName = NewPropName) then Exit;
539
540 FSynObjectPartList := NewSynObjectPartList;
541 FClassesList := NewClassesList;
542 if assigned(FClassesList) then
543 ClassComboBox.Items.Assign(FClassesList)
544 else
545 ClassComboBox.Clear;
546 if ClassComboBox.Items.Count >0 then
547 ClassComboBox.ItemIndex := 0;
548
549 // Can not use NewOwnerPersistent since it points to the SynGutter
550 if NewSynObjectPartList <> nil then
551 FOwnerPersistent := NewSynObjectPartList.Owner // The SynEdit
552 else
553 FOwnerPersistent := nil;
554
555 FPropertyName := NewPropName;
556 //debugln('TSynObjectPartListPropertyEditorForm.SetSynObjectPartList A SynObjectPartList=',dbgsName(FSynObjectPartList),' OwnerPersistent=',dbgsName(OwnerPersistent),' PropName=',PropertyName);
557 if GlobalDesignHook <> nil then
558 begin
559 if FOwnerPersistent <> nil then
560 begin
561 GlobalDesignHook.AddHandlerComponentRenamed(@ComponentRenamed);
562 GlobalDesignHook.AddHandlerPersistentDeleting(@PersistentDeleting);
563 GlobalDesignHook.AddHandlerRefreshPropertyValues(@RefreshPropertyValues);
564 end
565 else
566 begin
567 GlobalDesignHook.RemoveAllHandlersForObject(Self);
568 end;
569 end;
570
571 FillSynObjectPartsListBox;
572 UpdateCaption;
573 end;
574
575 procedure TSynObjectPartListPropertyEditorForm.Modified;
576 begin
577 GlobalDesignHook.Modified(Self);
578 //SelectInObjectInspector(False);
579 end;
580
581 { TSynPropertyEditObjectList }
582
ReadElementCountnull583 function TSynPropertyEditObjectList.ReadElementCount: integer;
584 var
585 SynObjectList: TObject;
586 begin
587 SynObjectList := GetObjectValue;
588 if SynObjectList is TSynObjectList then
589 Result := TSynObjectList(SynObjectList).Count
590 else
591 Result:=0;
592 end;
593
TSynPropertyEditObjectList.ReadElementnull594 function TSynPropertyEditObjectList.ReadElement(Index: integer): TPersistent;
595 var
596 SynObjectList: TSynObjectList;
597 begin
598 SynObjectList := TSynObjectList(GetObjectValue);
599 Result := SynObjectList.BaseItems[Index];
600 end;
601
GetAttributesnull602 function TSynPropertyEditObjectList.GetAttributes: TPropertyAttributes;
603 begin
604 Result := [paDialog, paReadOnly];
605 end;
606
607 procedure TSynPropertyEditObjectList.Edit;
608 var
609 TheSynObjectList: TSynObjectList;
610 begin
611 TheSynObjectList := TSynObjectList(GetObjectValue);
612 if TheSynObjectList = nil then
613 raise Exception.Create('ObjectPartList=nil');
614 ShowClassListEditor(TheSynObjectList, GetComponent(0), GetName);
615 end;
616
TSynPropertyEditObjectList.ShowClassListEditornull617 class function TSynPropertyEditObjectList.ShowClassListEditor(AClassList: TSynObjectList;
618 OwnerPersistent: TPersistent; const PropName: String): TCustomForm;
619 begin
620 if SynObjectPartListForm = nil then
621 SynObjectPartListForm := TSynObjectPartListPropertyEditorForm.Create(Application);
622 SynObjectPartListForm.SetSynObjectPartList(AClassList, ClassList, OwnerPersistent, PropName);
623 SynObjectPartListForm.EnsureVisible;
624 Result := SynObjectPartListForm;
625 end;
626
627 { TSynPropertyEditGutterPartList }
628
TSynPropertyEditGutterPartList.ClassListnull629 class function TSynPropertyEditGutterPartList.ClassList: TStringList;
630 begin
631 Result := KnownSynGutterPartClasses;
632 end;
633
634 initialization
635 if KnownSynGutterPartClasses = nil then
636 KnownSynGutterPartClasses := TStringList.Create;
637
638 finalization
639 FreeAndNil(KnownSynGutterPartClasses);
640
641 end.
642
643