1 {
2 /***************************************************************************
3 CodeExplOpts.pas
4 -------------------
5
6 ***************************************************************************/
7
8 ***************************************************************************
9 * *
10 * This source is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This code is distributed in the hope that it will be useful, but *
16 * WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
18 * General Public License for more details. *
19 * *
20 * A copy of the GNU General Public License is available on the World *
21 * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
22 * obtain it by writing to the Free Software Foundation, *
23 * Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. *
24 * *
25 ***************************************************************************
26
27 Abstract:
28 Dialog for the options of the code explorer.
29 }
30 unit CodeExplOpts;
31
32 {$mode objfpc}{$H+}
33
34 interface
35
36 uses
37 // RTL + FCL
38 Classes, SysUtils, Laz_AVL_Tree,
39 // LCL
40 LCLProc, Forms, Controls, Graphics, Dialogs, Buttons,
41 // CodeTools
42 BasicCodeTools, FileProcs,
43 // LazUtils
44 AvgLvlTree, Laz2_XMLCfg, LazFileUtils, LazFileCache,
45 // IDEIntf
46 IDEOptionsIntf, IDEOptEditorIntf,
47 // IDE
48 LazConf, IDEProcs, LazarusIDEStrConsts;
49
50 type
51 { TCodeExplorerOptions }
52
53 TCodeExplorerPage = (
54 cepNone,
55 cepCode,
56 cepDirectives
57 );
58
59 TCodeExplorerRefresh = (
60 cerManual, // only via refresh button
61 cerSwitchEditorPage,// everytime the source editor switches to another page
62 cerOnIdle // on idle
63 );
64
65 TCodeExplorerMode = (
66 cemCategory, // Category - Delphi like
67 cemSource // Follows Source Code
68 );
69
70 TCodeExplorerCategory = (
71 cecNone,
72 cecUses,
73 cecTypes,
74 cecVariables,
75 cecConstants,
76 cecProperties,
77 cecProcedures,
78 cecCodeObserver,
79 cecSurrounding
80 );
81 TCodeExplorerCategories = set of TCodeExplorerCategory;
82
83 TCEObserverCategory = (
84 cefcLongProcs, // procedures with many lines of code
85 cefcLongParamLists, // procedures with many parameters
86 cefcEmptyProcs, // procs without code (can contain comments)
87 cefcNestedProcs, // procs with a lot of nested sub procs
88 cefcUnnamedConsts, // numbers, strings in statements
89 cefcEmptyBlocks, // empty begin..end block (not even a comment)
90 cefcWrongIndentation, // possible missing lines or begin blocks
91 cefcPublishedPropWithoutDefault, // published properties without default specifier
92 cefcUnsortedClassVisibility, // public,private,protected,published keywords are not sorted
93 cefcEmptyClassSections, // empty public,private,protected,published section
94 cefcUnsortedClassMembers, // member of a public,private,protected,published section is not sorted alphabetically
95 cefcToDos // todo comment
96 );
97 TCEObserverCategories = set of TCEObserverCategory;
98
99 TCEObserverCategoryGroup = (ocgComplexity, ocgEmpty, ocgStyle, ocgOther);
100
101 const
102 FirstCodeExplorerCategory = cecUses;
103 DefaultCodeExplorerCategories = [cecUses,
104 cecTypes,cecVariables,cecConstants,cecProcedures];
105 cefcAll = [low(TCEObserverCategory)..high(TCEObserverCategory)];
106 DefaultCodeExplorerPage = cepCode;
107 DefaultCodeObserverCategories = [
108 cefcLongProcs,
109 cefcEmptyProcs,
110 cefcUnnamedConsts,
111 cefcEmptyBlocks,
112 cefcWrongIndentation,
113 cefcPublishedPropWithoutDefault,
114 cefcToDos
115 ];
116 DefaultCOLongProcLineCount = 50;
117 DefaultCOLongParamListCount = 6;
118 DefaultCONestedProcCount = 3;
119 DefaultCOureCharConst = false;
120 DefaultCOIgnoreConstants: array[1..2] of ansistring // Note: keep this asciiz
121 = (
122 '0',
123 '1'
124 );
125 DefaultCOIgnoreConstInFuncs: array[1..15] of ansistring // Note: keep this asciiz
126 = (
127 'Assert',
128 'Debug',
129 'DebugLn',
130 'DbgOut',
131 'write',
132 'writeln',
133 'Format',
134 'FormatBuf',
135 'StrFmt',
136 'StrLFmt',
137 'FmtStr',
138 'FloatToStrF',
139 'FloatToStr',
140 'CurrToStrF',
141 'FormatDateTime'
142 );
143
144 type
145
146 TCodeExplorerOptions = class(TAbstractIDEEnvironmentOptions)
147 private
148 FCategories: TCodeExplorerCategories;
149 FChangeStep: integer;
150 FObserveCharConst: boolean;
151 FCOIgnoreConstInFuncs: TStringToStringTree;
152 FLongParamListCount: integer;
153 FLongProcLineCount: integer;
154 FNestedProcCount: integer;
155 FObserverCategories: TCEObserverCategories;
156 FFollowCursor: boolean;
157 FMode : TCodeExplorerMode;
158 FObserverIgnoreConstants: TAvlTree;// tree of AnsiString
159 FOptionsFilename: string;
160 FPage: TCodeExplorerPage;
161 FRefresh: TCodeExplorerRefresh;
162 FSavedChangeStep: integer;
GetModifiednull163 function GetModified: boolean;
164 procedure SetCategories(const AValue: TCodeExplorerCategories);
165 procedure SetFollowCursor(const AValue: boolean);
166 procedure SetLongParamListCount(const AValue: integer);
167 procedure SetLongProcLineCount(const AValue: integer);
168 procedure SetMode(const AValue: TCodeExplorerMode);
169 procedure SetModified(AValue: boolean);
170 procedure SetNestedProcCount(const AValue: integer);
171 procedure SetObserveCharConst(const AValue: boolean);
172 procedure SetObserverCategories(const AValue: TCEObserverCategories);
173 procedure SetPage(AValue: TCodeExplorerPage);
174 procedure SetRefresh(const AValue: TCodeExplorerRefresh);
175 public
GetGroupCaptionnull176 class function GetGroupCaption:string; override;
GetInstancenull177 class function GetInstance: TAbstractIDEOptions; override;
178 procedure DoAfterWrite(Restore: boolean); override;
179 public
180 constructor Create;
181 destructor Destroy; override;
182 procedure Clear;
183 procedure Assign(Source: TPersistent); override;
184 procedure Load;
185 procedure Save;
186 procedure LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string);
187 procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string);
188 procedure IncreaseChangeStep;
189 property Modified: boolean read GetModified write SetModified;
190 public
191 // observer: ignore constants
CreateListOfCOIgnoreConstantsnull192 function CreateListOfCOIgnoreConstants: TStrings;
193 procedure SetListOf_COIgnoreConstants(List: TStrings; Add: boolean);
COIgnoreConstantnull194 function COIgnoreConstant(p: PChar): boolean;// test if atom is in COIgnoreConstants
COIgnoreConstants_AreDefaultnull195 function COIgnoreConstants_AreDefault(Exactly: boolean): boolean; // true if COIgnoreConstants contain/are default values
COIgnoreConstant_IsDefaultnull196 function COIgnoreConstant_IsDefault(const Atom: string): boolean; // true if Atom is in default values
197 procedure Add_COIgnoreConstant(const Atom: string);
198 procedure Clear_COIgnoreConstants;
199 procedure LoadDefaults_COIgnoreConstants;
200 public
201 // observer: ignore constants in functions
CreateListOfCOIgnoreConstInFuncsnull202 function CreateListOfCOIgnoreConstInFuncs: TStrings;
203 procedure SetListOf_COIgnoreConstInFuncs(List: TStrings; Add: boolean);
COIgnoreConstInFuncnull204 function COIgnoreConstInFunc(const Func: string): boolean;// test if function is in COIgnoreConstInFuncs
205 function COIgnoreConstInFuncs_AreDefault(Exactly: boolean): boolean; // true if COIgnoreConstInFuncs contain/are default values
COIgnoreConstInFuncs_IsDefaultnull206 function COIgnoreConstInFuncs_IsDefault(const Func: string): boolean; // true if Atom is in default values
207 procedure Add_COIgnoreConstInFuncs(const Func: string);
208 procedure Clear_COIgnoreConstInFuncs;
209 procedure LoadDefaults_COIgnoreConstInFuncs;
210 public
211 property Refresh: TCodeExplorerRefresh read FRefresh write SetRefresh default cerSwitchEditorPage;
212 property Mode: TCodeExplorerMode read FMode write SetMode default cemCategory;
213 property OptionsFilename: string read FOptionsFilename write FOptionsFilename;
214 property FollowCursor: boolean read FFollowCursor write SetFollowCursor default true;
215 property Categories: TCodeExplorerCategories read FCategories write SetCategories default DefaultCodeExplorerCategories;
216 property Page: TCodeExplorerPage read FPage write SetPage default DefaultCodeExplorerPage;
217 property ChangeStep: integer read FChangeStep write FChangeStep;
218 public
219 // Observer
220 property ObserveCharConst: boolean read FObserveCharConst write SetObserveCharConst default DefaultCOureCharConst;
221 property ObserverCategories: TCEObserverCategories read FObserverCategories write SetObserverCategories default DefaultCodeObserverCategories;
222 property ObserverIgnoreConstants: TAvlTree read FObserverIgnoreConstants;
223 property COIgnoreConstInFuncs: TStringToStringTree read FCOIgnoreConstInFuncs;
224 property LongParamListCount: integer read FLongParamListCount write SetLongParamListCount default DefaultCOLongParamListCount;
225 property LongProcLineCount: integer read FLongProcLineCount write SetLongProcLineCount default DefaultCOLongProcLineCount;
226 property NestedProcCount: integer read FNestedProcCount write SetNestedProcCount default DefaultCONestedProcCount;
227 end;
228
229 const
230 CodeExplorerVersion = 1;
231
232 cerDefault = cerSwitchEditorPage;
233
234 CodeExplorerPageNames: array[TCodeExplorerPage] of string = (
235 '?',
236 'Code',
237 'Directives'
238 );
239 CodeExplorerRefreshNames: array[TCodeExplorerRefresh] of string = (
240 'Manual',
241 'SwitchEditorPage',
242 'OnIdle'
243 );
244 CodeExplorerModeNames: array[TCodeExplorerMode] of string = (
245 'Category',
246 'Source'
247 );
248 CodeExplorerCategoryNames: array[TCodeExplorerCategory] of string = (
249 '?',
250 'Uses',
251 'Types',
252 'Variables',
253 'Constants',
254 'Properties',
255 'Procedures',
256 'CodeObserver',
257 'Surrounding'
258 );
259 CodeObserverCategoryNames: array[TCEObserverCategory] of string = (
260 'LongProcs',
261 'LongParamLists',
262 'EmptyProcs',
263 'NestedProcs',
264 'UnnamedConsts',
265 'EmptyBlocks',
266 'WrongIndentation',
267 'PublishedPropWithoutDefault',
268 'UnsortedClassVisibility',
269 'EmptyClassSections',
270 'UnsortedClassMembers',
271 'ToDos'
272 );
273
274 var
275 CodeExplorerOptions: TCodeExplorerOptions = nil; // set by the IDE
276
CodeExplorerPageNameToEnumnull277 function CodeExplorerPageNameToEnum(const s: string): TCodeExplorerPage;
CodeExplorerRefreshNameToEnumnull278 function CodeExplorerRefreshNameToEnum(const s: string): TCodeExplorerRefresh;
CodeExplorerModeNameToEnumnull279 function CodeExplorerModeNameToEnum(const s: string): TCodeExplorerMode;
CodeExplorerCategoryNameToEnumnull280 function CodeExplorerCategoryNameToEnum(const s: string): TCodeExplorerCategory;
CodeExplorerLocalizedStringnull281 function CodeExplorerLocalizedString(const c: TCodeExplorerCategory): string;
CodeObserverCatNameToEnumnull282 function CodeObserverCatNameToEnum(const s: string): TCEObserverCategory;
CodeExplorerLocalizedStringnull283 function CodeExplorerLocalizedString(const c: TCEObserverCategory): string;
dbgsnull284 function dbgs(c: TCodeExplorerCategory): string; overload;
285
286 implementation
287
CodeExplorerPageNameToEnumnull288 function CodeExplorerPageNameToEnum(const s: string): TCodeExplorerPage;
289 begin
290 for Result:=Low(TCodeExplorerPage) to High(TCodeExplorerPage) do
291 if SysUtils.CompareText(CodeExplorerPageNames[Result],s)=0 then exit;
292 Result:=DefaultCodeExplorerPage;
293 end;
294
CodeExplorerRefreshNameToEnumnull295 function CodeExplorerRefreshNameToEnum(const s: string): TCodeExplorerRefresh;
296 begin
297 for Result:=Low(TCodeExplorerRefresh) to High(TCodeExplorerRefresh) do
298 if SysUtils.CompareText(CodeExplorerRefreshNames[Result],s)=0 then exit;
299 Result:=cerDefault;
300 end;
301
CodeExplorerModeNameToEnumnull302 function CodeExplorerModeNameToEnum(const s: string): TCodeExplorerMode;
303 begin
304 for Result:=Low(TCodeExplorerMode) to High(TCodeExplorerMode) do
305 if SysUtils.CompareText(CodeExplorerModeNames[Result],s)=0 then exit;
306 Result:=cemCategory;
307 end;
308
CodeExplorerCategoryNameToEnumnull309 function CodeExplorerCategoryNameToEnum(const s: string): TCodeExplorerCategory;
310 begin
311 for Result:=FirstCodeExplorerCategory to High(TCodeExplorerCategory) do
312 if SysUtils.CompareText(CodeExplorerCategoryNames[Result],s)=0 then exit;
313 Result:=cecTypes;
314 end;
315
CodeExplorerLocalizedStringnull316 function CodeExplorerLocalizedString(const c: TCodeExplorerCategory): string;
317 begin
318 case c of
319 cecUses: Result:=lisCEUses;
320 cecTypes: Result:=lisCETypes;
321 cecVariables: Result:=lisCEVariables;
322 cecConstants: Result:=lisCEConstants;
323 cecProcedures: Result:=lisCEProcedures;
324 cecProperties: Result:=lisCEProperties;
325 cecCodeObserver: Result:=lisCodeObserver;
326 cecSurrounding: Result:=lisCESurrounding;
327 else Result:='?';
328 end;
329 end;
330
CodeObserverCatNameToEnumnull331 function CodeObserverCatNameToEnum(const s: string): TCEObserverCategory;
332 begin
333 for Result:=low(TCEObserverCategory) to High(TCEObserverCategory) do
334 if SysUtils.CompareText(CodeObserverCategoryNames[Result],s)=0 then exit;
335 Result:=cefcLongProcs;
336 end;
337
CodeExplorerLocalizedStringnull338 function CodeExplorerLocalizedString(const c: TCEObserverCategory): string;
339 begin
340 case c of
341 cefcLongProcs: Result:=lisCELongProcedures;
342 cefcLongParamLists: Result:=lisCEManyParameters;
343 cefcEmptyProcs: Result:=lisCEEmptyProcedures;
344 cefcNestedProcs: Result:=lisCEManyNestedProcedures;
345 cefcUnnamedConsts: Result:=lisCEUnnamedConstants;
346 cefcEmptyBlocks: Result:=lisCEEmptyBlocks;
347 cefcWrongIndentation: Result:=lisCEWrongIndentation;
348 cefcPublishedPropWithoutDefault: Result:=lisCEPublishedPropertyWithoutDefault;
349 cefcUnsortedClassVisibility: Result:=lisCEUnsortedVisibility;
350 cefcEmptyClassSections: Result:=lisCEEmptyClassSections;
351 cefcUnsortedClassMembers: Result:=lisCEUnsortedMembers;
352 cefcToDos: Result:=lisCEToDos;
353 else Result:='?';
354 end;
355 end;
356
dbgsnull357 function dbgs(c: TCodeExplorerCategory): string;
358 begin
359 Result:=CodeExplorerCategoryNames[c];
360 end;
361
362 { TCodeExplorerOptions }
363
364 procedure TCodeExplorerOptions.SetRefresh(const AValue: TCodeExplorerRefresh);
365 begin
366 if FRefresh=AValue then exit;
367 FRefresh:=AValue;
368 IncreaseChangeStep;
369 end;
370
371 procedure TCodeExplorerOptions.SetMode(const AValue: TCodeExplorerMode);
372 begin
373 if FMode=AValue then exit;
374 FMode:=AValue;
375 IncreaseChangeStep;
376 end;
377
378 procedure TCodeExplorerOptions.SetModified(AValue: boolean);
379 begin
380 if AValue then
381 IncreaseChangeStep
382 else
383 FSavedChangeStep:=FChangeStep;
384 end;
385
386 procedure TCodeExplorerOptions.SetNestedProcCount(const AValue: integer);
387 begin
388 if FNestedProcCount=AValue then exit;
389 FNestedProcCount:=AValue;
390 IncreaseChangeStep;
391 end;
392
393 procedure TCodeExplorerOptions.SetObserveCharConst(const AValue: boolean);
394 begin
395 if FObserveCharConst=AValue then exit;
396 FObserveCharConst:=AValue;
397 IncreaseChangeStep;
398 end;
399
400 procedure TCodeExplorerOptions.SetObserverCategories(
401 const AValue: TCEObserverCategories);
402 begin
403 if FObserverCategories=AValue then exit;
404 FObserverCategories:=AValue;
405 IncreaseChangeStep;
406 end;
407
408 procedure TCodeExplorerOptions.SetPage(AValue: TCodeExplorerPage);
409 begin
410 if FPage=AValue then Exit;
411 FPage:=AValue;
412 IncreaseChangeStep;
413 end;
414
415 procedure TCodeExplorerOptions.SetFollowCursor(const AValue: boolean);
416 begin
417 if FFollowCursor=AValue then exit;
418 FFollowCursor:=AValue;
419 IncreaseChangeStep;
420 end;
421
422 procedure TCodeExplorerOptions.SetLongParamListCount(const AValue: integer);
423 begin
424 if FLongParamListCount=AValue then exit;
425 FLongParamListCount:=AValue;
426 IncreaseChangeStep;
427 end;
428
429 procedure TCodeExplorerOptions.SetLongProcLineCount(const AValue: integer);
430 begin
431 if FLongProcLineCount=AValue then exit;
432 FLongProcLineCount:=AValue;
433 IncreaseChangeStep;
434 end;
435
436 procedure TCodeExplorerOptions.SetCategories(
437 const AValue: TCodeExplorerCategories);
438 begin
439 if FCategories=AValue then exit;
440 FCategories:=AValue;
441 IncreaseChangeStep;
442 end;
443
TCodeExplorerOptions.GetModifiednull444 function TCodeExplorerOptions.GetModified: boolean;
445 begin
446 Result:=FSavedChangeStep<>FChangeStep;
447 end;
448
449 constructor TCodeExplorerOptions.Create;
450 begin
451 FOptionsFilename:=AppendPathDelim(GetPrimaryConfigPath)+'codeexploreroptions.xml';
452 FObserverIgnoreConstants:=TAvlTree.Create(TListSortCompare(@CompareAtom));
453 FCOIgnoreConstInFuncs:=TStringToStringTree.Create(false);
454 Clear;
455 LoadDefaults_COIgnoreConstants;
456 LoadDefaults_COIgnoreConstInFuncs;
457 end;
458
459 destructor TCodeExplorerOptions.Destroy;
460 begin
461 Clear_COIgnoreConstants;
462 FreeAndNil(FObserverIgnoreConstants);
463 FreeAndNil(FCOIgnoreConstInFuncs);
464 inherited Destroy;
465 end;
466
TCodeExplorerOptions.GetGroupCaptionnull467 class function TCodeExplorerOptions.GetGroupCaption: string;
468 begin
469 Result := dlgGroupCodeExplorer;
470 end;
471
TCodeExplorerOptions.GetInstancenull472 class function TCodeExplorerOptions.GetInstance: TAbstractIDEOptions;
473 begin
474 Result := CodeExplorerOptions;
475 end;
476
477 procedure TCodeExplorerOptions.DoAfterWrite(Restore: boolean);
478 begin
479 if not Restore then
480 Save;
481 end;
482
483 procedure TCodeExplorerOptions.Clear;
484 begin
485 IncreaseChangeStep;
486 FMode:=cemCategory;
487 FRefresh:=cerDefault;
488 FFollowCursor:=true;
489 FPage:=DefaultCodeExplorerPage;
490 FCategories:=DefaultCodeExplorerCategories;
491 FObserverCategories:=DefaultCodeObserverCategories;
492 FLongProcLineCount:=DefaultCOLongProcLineCount;
493 FLongParamListCount:=DefaultCOLongParamListCount;
494 FNestedProcCount:=DefaultCONestedProcCount;
495 FObserveCharConst:=DefaultCOureCharConst;
496 Clear_COIgnoreConstants;
497 Clear_COIgnoreConstInFuncs;
498 end;
499
500 procedure TCodeExplorerOptions.Assign(Source: TPersistent);
501 var
502 Src: TCodeExplorerOptions;
503 List: TStrings;
504 begin
505 if Source is TCodeExplorerOptions then begin
506 IncreaseChangeStep;
507 Src:=TCodeExplorerOptions(Source);
508 FRefresh:=Src.Refresh;
509 FMode:=Src.Mode;
510 FFollowCursor:=Src.FollowCursor;
511 FPage:=Src.Page;
512 FCategories:=Src.Categories;
513 FObserverCategories:=Src.ObserverCategories;
514 FLongProcLineCount:=Src.LongProcLineCount;
515 FLongParamListCount:=Src.LongParamListCount;
516 FNestedProcCount:=Src.NestedProcCount;
517 FObserveCharConst:=Src.ObserveCharConst;
518 List:=Src.CreateListOfCOIgnoreConstants;
519 try
520 SetListOf_COIgnoreConstants(List,false);
521 finally
522 List.Free;
523 end;
524 List:=Src.CreateListOfCOIgnoreConstInFuncs;
525 try
526 SetListOf_COIgnoreConstInFuncs(List,false);
527 finally
528 List.Free;
529 end;
530 end else
531 inherited Assign(Source);
532 end;
533
534 procedure TCodeExplorerOptions.Load;
535 var
536 XMLConfig: TXMLConfig;
537 //FileVersion: integer;
538 begin
539 if not FileExistsUTF8(FOptionsFilename) then
540 begin
541 Clear;
542 LoadDefaults_COIgnoreConstants;
543 LoadDefaults_COIgnoreConstInFuncs;
544 Exit;
545 end;
546 try
547 XMLConfig:=TXMLConfig.Create(FOptionsFilename);
548 //FileVersion:=XMLConfig.GetValue('CodeExplorer/Version/Value',0);
549 LoadFromXMLConfig(XMLConfig,'CodeExplorer/');
550 XMLConfig.Free;
551 except
552 on E: Exception do begin
553 DebugLn('[TCodeExplorerOptions.Load] error reading "',FOptionsFilename,'" ',E.Message);
554 end;
555 end;
556 end;
557
558 procedure TCodeExplorerOptions.Save;
559 var
560 XMLConfig: TXMLConfig;
561 begin
562 if FileExistsCached(FOptionsFilename) and not Modified then exit;
563 try
564 InvalidateFileStateCache;
565 XMLConfig:=TXMLConfig.CreateClean(FOptionsFilename);
566 XMLConfig.SetDeleteValue('CodeExplorer/Version/Value',
567 CodeExplorerVersion,0);
568 SaveToXMLConfig(XMLConfig,'CodeExplorer/');
569 XMLConfig.Flush;
570 XMLConfig.Free;
571 Modified:=false;
572 except
573 on E: Exception do begin
574 DebugLn('[TCodeExplorerOptions.Save] error writing "',FOptionsFilename,'" ',E.Message);
575 end;
576 end;
577 end;
578
579 procedure TCodeExplorerOptions.LoadFromXMLConfig(XMLConfig: TXMLConfig;
580 const Path: string);
581 var
582 c: TCodeExplorerCategory;
583 f: TCEObserverCategory;
584 CurPath: String;
585 List: TStringList;
586 begin
587 IncreaseChangeStep;
588 Clear;
589 FRefresh:=CodeExplorerRefreshNameToEnum(
590 XMLConfig.GetValue(Path+'Refresh/Value',''));
591 FMode:=CodeExplorerModeNameToEnum(
592 XMLConfig.GetValue(Path+'Mode/Value',''));
593 FFollowCursor:=XMLConfig.GetValue(Path+'FollowCursor',true);
594 FPage:=CodeExplorerPageNameToEnum(XMLConfig.GetValue(Path+'Page/Value',''));
595
596 FCategories:=[];
597 for c:=FirstCodeExplorerCategory to high(TCodeExplorerCategory) do
598 if XMLConfig.GetValue(Path+'Categories/'+CodeExplorerCategoryNames[c],
599 c in DefaultCodeExplorerCategories) then
600 Include(FCategories,c);
601 FObserverCategories:=[];
602 for f:=low(TCEObserverCategory) to high(TCEObserverCategory) do
603 begin
604 CurPath:=Path+'CodeObserver/'+CodeObserverCategoryNames[f]+'/';
605 if XMLConfig.GetValue(CurPath+'Show',f in DefaultCodeObserverCategories)
606 then
607 Include(FObserverCategories,f);
608 case f of
609 cefcLongProcs:
610 FLongProcLineCount:=XMLConfig.GetValue(CurPath+'LineCount/Value',
611 DefaultCOLongProcLineCount);
612 cefcLongParamLists:
613 FLongParamListCount:=XMLConfig.GetValue(CurPath+'Count/Value',
614 DefaultCOLongParamListCount);
615 cefcNestedProcs:
616 FNestedProcCount:=XMLConfig.GetValue(CurPath+'Count/Value',
617 DefaultCONestedProcCount);
618 cefcUnnamedConsts:
619 begin
620 FObserveCharConst:=XMLConfig.GetValue(CurPath+'CharConsts/Value',
621 DefaultCOureCharConst);
622 // load standard ObserverIgnoreConstants
623 if XMLConfig.GetValue(CurPath+'Ignore/ContainsDefaults',true) then
624 LoadDefaults_COIgnoreConstants;
625 // load custom ObserverIgnoreConstants
626 List:=TStringList.Create;
627 try
628 LoadStringList(XMLConfig,List,CurPath+'Ignore/');
629 SetListOf_COIgnoreConstants(List,true);
630 finally
631 List.Free;
632 end;
633 // load standard COIgnoreConstInFuncs
634 if XMLConfig.GetValue(CurPath+'IgnoreInFuncs/ContainsDefaults',true) then
635 LoadDefaults_COIgnoreConstInFuncs;
636 // load custom COIgnoreConstInFuncs
637 List:=TStringList.Create;
638 try
639 LoadStringList(XMLConfig,List,CurPath+'IgnoreFuncs/');
640 SetListOf_COIgnoreConstInFuncs(List,true);
641 finally
642 List.Free;
643 end;
644 end;
645 end;
646 end;
647 end;
648
649 procedure TCodeExplorerOptions.SaveToXMLConfig(XMLConfig: TXMLConfig;
650 const Path: string);
651 var
652 c: TCodeExplorerCategory;
653 f: TCEObserverCategory;
654 CurPath: String;
655 List: TStrings;
656 ContainsDefaults: Boolean;
657 i: Integer;
658 begin
659 XMLConfig.SetDeleteValue(Path+'Refresh/Value',
660 CodeExplorerRefreshNames[FRefresh],
661 CodeExplorerRefreshNames[cerDefault]);
662 XMLConfig.SetDeleteValue(Path+'Mode/Value',
663 CodeExplorerModeNames[FMode],
664 CodeExplorerModeNames[cemCategory]);
665 XMLConfig.SetDeleteValue(Path+'FollowCursor',FFollowCursor,true);
666 XMLConfig.SetDeleteValue(Path+'Page/Value',CodeExplorerPageNames[FPage],
667 CodeExplorerPageNames[DefaultCodeExplorerPage]);
668
669 for c:=FirstCodeExplorerCategory to high(TCodeExplorerCategory) do
670 XMLConfig.SetDeleteValue(Path+'Categories/'+CodeExplorerCategoryNames[c],
671 c in FCategories,c in DefaultCodeExplorerCategories);
672 for f:=low(TCEObserverCategory) to high(TCEObserverCategory) do
673 begin
674 CurPath:=Path+'CodeObserver/'+CodeObserverCategoryNames[f]+'/';
675 XMLConfig.SetDeleteValue(CurPath+'Show',
676 f in FObserverCategories,f in DefaultCodeObserverCategories);
677 case f of
678 cefcLongProcs:
679 XMLConfig.SetDeleteValue(CurPath+'LineCount/Value',
680 FLongProcLineCount,DefaultCOLongProcLineCount);
681 cefcLongParamLists:
682 XMLConfig.SetDeleteValue(CurPath+'Count/Value',
683 FLongParamListCount,DefaultCOLongParamListCount);
684 cefcNestedProcs:
685 XMLConfig.SetDeleteValue(CurPath+'Count/Value',
686 FNestedProcCount,DefaultCONestedProcCount);
687 cefcUnnamedConsts:
688 begin
689 XMLConfig.SetDeleteValue(CurPath+'CharConsts/Value',
690 FObserveCharConst,DefaultCOureCharConst);
691 // save standard ObserverIgnoreConstants
692 ContainsDefaults:=COIgnoreConstants_AreDefault(false);
693 XMLConfig.SetDeleteValue(CurPath+'Ignore/ContainsDefaults',
694 ContainsDefaults,true);
695 // save ObserverIgnoreConstants
696 List:=CreateListOfCOIgnoreConstants;
697 try
698 for i:=List.Count-1 downto 0 do
699 if COIgnoreConstant_IsDefault(List[i]) then
700 List.Delete(i);
701 SaveStringList(XMLConfig,List,CurPath+'Ignore/');
702 finally
703 List.Free;
704 end;
705 // save standard COIgnoreConstInFuncs
706 ContainsDefaults:=COIgnoreConstInFuncs_AreDefault(false);
707 XMLConfig.SetDeleteValue(CurPath+'IgnoreInFuncs/ContainsDefaults',
708 ContainsDefaults,true);
709 // save COIgnoreConstInFuncs
710 List:=CreateListOfCOIgnoreConstInFuncs;
711 try
712 for i:=List.Count-1 downto 0 do
713 if COIgnoreConstInFuncs_IsDefault(List[i]) then
714 List.Delete(i);
715 SaveStringList(XMLConfig,List,CurPath+'IgnoreInFuncs/');
716 finally
717 List.Free;
718 end;
719 end;
720 end;
721 end;
722 end;
723
724 procedure TCodeExplorerOptions.IncreaseChangeStep;
725 begin
726 if FChangeStep=high(integer) then
727 FChangeStep:=low(integer)
728 else
729 inc(FChangeStep);
730 end;
731
CreateListOfCOIgnoreConstantsnull732 function TCodeExplorerOptions.CreateListOfCOIgnoreConstants: TStrings;
733 var
734 AVLNode: TAvlTreeNode;
735 s: String;
736 begin
737 Result:=TStringList.Create;
738 AVLNode:=ObserverIgnoreConstants.FindLowest;
739 while AVLNode<>nil do begin
740 s:=GetAtomString(PChar(AVLNode.Data),false);
741 if s<>'' then
742 Result.Add(s);
743 AVLNode:=ObserverIgnoreConstants.FindSuccessor(AVLNode);
744 end;
745 end;
746
747 procedure TCodeExplorerOptions.Clear_COIgnoreConstants;
748 var
749 AVLNode: TAvlTreeNode;
750 s: String;
751 begin
752 if FObserverIgnoreConstants.Count=0 then exit;
753 IncreaseChangeStep;
754 s:='';
755 AVLNode:=FObserverIgnoreConstants.FindLowest;
756 while AVLNode<>nil do begin
757 // decrease reference counter
758 Pointer(s):=AVLNode.Data;
759 s:='';
760 AVLNode:=FObserverIgnoreConstants.FindSuccessor(AVLNode);
761 end;
762 if s='' then ; // omit fpc note
763 FObserverIgnoreConstants.Clear;
764 end;
765
766 procedure TCodeExplorerOptions.SetListOf_COIgnoreConstants(List: TStrings;
767 Add: boolean);
768 var
769 i: Integer;
770 begin
771 IncreaseChangeStep;
772 if not Add then
773 Clear_COIgnoreConstants;
774 for i:=0 to List.Count-1 do
775 Add_COIgnoreConstant(List[i]);
776 end;
777
778 procedure TCodeExplorerOptions.LoadDefaults_COIgnoreConstants;
779 var
780 i: Integer;
781 begin
782 if COIgnoreConstants_AreDefault(true) then exit;
783 IncreaseChangeStep;
784 Clear_COIgnoreConstants;
785 for i:=low(DefaultCOIgnoreConstants) to high(DefaultCOIgnoreConstants) do
786 Add_COIgnoreConstant(DefaultCOIgnoreConstants[i]);
787 end;
788
TCodeExplorerOptions.CreateListOfCOIgnoreConstInFuncsnull789 function TCodeExplorerOptions.CreateListOfCOIgnoreConstInFuncs: TStrings;
790 var
791 AVLNode: TAvlTreeNode;
792 s: String;
793 begin
794 Result:=TStringList.Create;
795 AVLNode:=COIgnoreConstInFuncs.Tree.FindLowest;
796 while AVLNode<>nil do begin
797 s:=PStringToStringItem(AVLNode.Data)^.Name;
798 if s<>'' then
799 Result.Add(s);
800 AVLNode:=COIgnoreConstInFuncs.Tree.FindSuccessor(AVLNode);
801 end;
802 end;
803
804 procedure TCodeExplorerOptions.SetListOf_COIgnoreConstInFuncs(List: TStrings;
805 Add: boolean);
806 var
807 i: Integer;
808 begin
809 IncreaseChangeStep;
810 if not Add then
811 Clear_COIgnoreConstInFuncs;
812 for i:=0 to List.Count-1 do
813 Add_COIgnoreConstInFuncs(List[i]);
814 end;
815
COIgnoreConstInFuncnull816 function TCodeExplorerOptions.COIgnoreConstInFunc(const Func: string): boolean;
817 begin
818 Result:=FCOIgnoreConstInFuncs.Contains(Func);
819 end;
820
COIgnoreConstInFuncs_AreDefaultnull821 function TCodeExplorerOptions.COIgnoreConstInFuncs_AreDefault(Exactly: boolean
822 ): boolean;
823 const
824 DefCount = high(DefaultCOIgnoreConstInFuncs)-Low(DefaultCOIgnoreConstInFuncs)+1;
825 var
826 i: Integer;
827 begin
828 if Exactly and (FCOIgnoreConstInFuncs.Count=DefCount) then
829 exit(false);
830 if FCOIgnoreConstInFuncs.Count<DefCount then exit(false);
831 for i:=low(DefaultCOIgnoreConstInFuncs) to high(DefaultCOIgnoreConstInFuncs) do
832 if not COIgnoreConstInFunc(DefaultCOIgnoreConstInFuncs[i]) then
833 exit(false);
834 Result:=true;
835 end;
836
TCodeExplorerOptions.COIgnoreConstInFuncs_IsDefaultnull837 function TCodeExplorerOptions.COIgnoreConstInFuncs_IsDefault(const Func: string
838 ): boolean;
839 var
840 i: Integer;
841 begin
842 for i:=low(DefaultCOIgnoreConstants) to high(DefaultCOIgnoreConstants) do
843 if SysUtils.CompareText(Func,DefaultCOIgnoreConstants[i])=0 then
844 exit(true);
845 Result:=false;
846 end;
847
848 procedure TCodeExplorerOptions.Add_COIgnoreConstInFuncs(const Func: string);
849 begin
850 if Func='' then exit;
851 if COIgnoreConstInFunc(Func) then exit;
852 IncreaseChangeStep;
853 FCOIgnoreConstInFuncs.Values[Func]:='';
854 end;
855
856 procedure TCodeExplorerOptions.Clear_COIgnoreConstInFuncs;
857 begin
858 if FCOIgnoreConstInFuncs.Count=0 then exit;
859 IncreaseChangeStep;
860 FCOIgnoreConstInFuncs.Clear;
861 end;
862
863 procedure TCodeExplorerOptions.LoadDefaults_COIgnoreConstInFuncs;
864 var
865 i: Integer;
866 begin
867 if COIgnoreConstInFuncs_AreDefault(true) then exit;
868 IncreaseChangeStep;
869 Clear_COIgnoreConstInFuncs;
870 for i:=low(DefaultCOIgnoreConstInFuncs) to high(DefaultCOIgnoreConstInFuncs) do
871 Add_COIgnoreConstInFuncs(DefaultCOIgnoreConstInFuncs[i]);
872 end;
873
TCodeExplorerOptions.COIgnoreConstantnull874 function TCodeExplorerOptions.COIgnoreConstant(p: PChar): boolean;
875 begin
876 Result:=FObserverIgnoreConstants.Find(p)<>nil;
877 end;
878
879 procedure TCodeExplorerOptions.Add_COIgnoreConstant(const Atom: string);
880 var
881 s: String;
882 begin
883 if Atom='' then exit;
884 if COIgnoreConstant(PChar(Atom)) then exit;
885 IncreaseChangeStep;
886 s:=Atom;
887 FObserverIgnoreConstants.Add(Pointer(s));
888 Pointer(s):=nil;
889 end;
890
TCodeExplorerOptions.COIgnoreConstants_AreDefaultnull891 function TCodeExplorerOptions.COIgnoreConstants_AreDefault(Exactly: boolean
892 ): boolean;
893 const
894 DefCount = high(DefaultCOIgnoreConstants)-Low(DefaultCOIgnoreConstants)+1;
895 var
896 i: Integer;
897 begin
898 if Exactly and (FObserverIgnoreConstants.Count=DefCount) then
899 exit(false);
900 if FObserverIgnoreConstants.Count<DefCount then exit(false);
901 for i:=low(DefaultCOIgnoreConstants) to high(DefaultCOIgnoreConstants) do
902 if not COIgnoreConstant(PChar(DefaultCOIgnoreConstants[i])) then
903 exit(false);
904 Result:=true;
905 end;
906
COIgnoreConstant_IsDefaultnull907 function TCodeExplorerOptions.COIgnoreConstant_IsDefault(const Atom: string
908 ): boolean;
909 var
910 i: Integer;
911 begin
912 for i:=low(DefaultCOIgnoreConstants) to high(DefaultCOIgnoreConstants) do
913 if CompareAtom(PChar(Atom),PChar(DefaultCOIgnoreConstants[i]),false)=0 then
914 exit(true);
915 Result:=false;
916 end;
917
918 initialization
919 RegisterIDEOptionsGroup(GroupCodeExplorer, TCodeExplorerOptions);
920 end.
921
922